将资源文件添加到karaf classpath

时间:2017-10-17 23:54:55

标签: java osgi classpath apache-karaf blueprint-osgi

我正在使用karaf 4.0.5和osgi进行项目。我们有客户端代码来调用REST API,这需要加载3个“* .properties”文件。我得到了一个客户端jar,我用它来调用服务器端类和方法(包含我无法更新的代码)。所需的属性文件存在于提供的客户端jar中,但它们的代码仍然无法找到并加载它们。

在调试我的pax考试时,我发现以下可能的原因是它没有从jar中加载资源文件。

  1. 加载文件的代码似乎只是尝试从Bundle Classloader和
  2. 加载资源
  3. 它调用“getResource()”方法而不是“getResourceAsStream()”方法。
  4. 或者,我尝试将资源添加到我的文件系统上的目录中,并将类路径附加到目录的位置,如:

    -cp .;C:/Users/abcUser/Desktop/resourceFolder/;

    (Windows 7,在使用来自eclipse的junit 4+执行pax考试时,将类路径条目添加为VM参数) - >这也不起作用,它仍然无法找到这些文件。 我还有哪些其他选项,以便Bundle Classloader找到这些文件?

    注意:我们已经有一堆其他* .cfg文件,其内容使用蓝图加载到bean中并在容器中注册,但这不是我在这里需要做的。在运行时,这些文件应该可用于BundleClassloader,并且应该通过“getResource()”方法检索。

    更新:按照接受的答案的以下部分,应用程序成功加载了属性文件。

      

    要检查的另一件事是客户端代码在尝试加载这些资源时是否实际使用了bundle classloader。在某些情况下,代码通过使用线程上下文类加载器来尝试变得聪明,在调用客户端代码之前需要对其进行适当的设置。

    来自客户端jar的代码完全按照猜测:使用Thread.currentThread().getContextClassLoader()进行资源加载。我能够将ContextLoader设置为CustomAbstractProcessor的类加载器,现在它从该包的类路径加载属性文件!

    ClassLoader previousCL = Thread.currentThread().getContextClassLoader();
    Thread.currentThread().setContextClassLoader(CustomAbstractProcessor.class.getClassLoader());
    try {
        //REST call to server using classes and methods from provided client jar.
    }
    finally {
        Thread.currentThread().setContextClassLoader(previousCL);
    }
    

1 个答案:

答案 0 :(得分:1)

  

我已经获得了一个客户端jar,我用它来调用服务器端类和方法(包含我无法更新的代码)。所需的属性文件存在于提供的客户端jar中,但是他们的代码仍然无法找到并加载它们。

如果这个客户端jar作为OSGi包运行,那么它应该能够使用自己的类加载器(bundle类加载器)找到资源,如果(并且仅当)资源在bundle的类路径上。

OSGi包的默认类路径是.,即包的根。这可以使用Bundle-ClassPath清单标头覆盖,并用于捆绑包中的一个或多个位置。

  • 一种可能性是客户端捆绑包具有不同的类路径集,并且属性文件不在其上。
  • 另一种可能性是属性文件位于类路径上,但是位置与预期的不匹配,例如代码正在寻找foo.properties,文件位于`/props/foo.properties'
  

它调用getResource()方法而不是getResourceAsStream()方法。

getResourceAsStream()只是getResource().openStream()的无效安全版本。

  

我还有哪些其他选项,以便Bundle Classloader找到这些文件?

要检查的另一件事是客户端代码在尝试加载这些资源时是否实际使用了bundle classloader。在某些情况下,代码通过使用线程上下文类加载器来尝试变得聪明,在调用客户端代码之前需要对其进行适当的设置。