将资源文件添加到 karaf 类路径

adding resource files to karaf classpath

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

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

  1. 加载文件的代码似乎试图仅从 Bundle Classloader 加载资源,并且
  2. 它调用“getResource()”方法而不是“getResourceAsStream()”方法。

或者,我尝试将资源添加到我的文件系统上的一个目录,并在类路径中附加目录的位置,如:

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

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

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

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

Another thing to check is whether the client code is actually using the bundle classloader when trying to load these resources. In some cases the code tries to be clever by using the Thread Context Classloader, which would need to be set appropriately before calling the client code.

来自客户端 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);
}

I have been given a client jar that I'm using to invoke the server side classes and methods (containing code that I cannot update). The required property files are present in the provided client jar, but their code still doesn't locate and load them.

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

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

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

it calls the getResource() method instead of the getResourceAsStream() method.

getResourceAsStream() 只是 getResource().openStream().

的 null-safe 版本

What other options do I have so the Bundle Classloader locates these files?

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