如何使OSGi中的所有包都可以看到资源文件?

时间:2017-10-27 08:17:36

标签: eclipse-plugin osgi apache-karaf apache-felix equinox

我想在我的包中包含一个资源文件(例如一些xml配置文件),并使其对容器中的所有其他包可见。是否可以不使用Fragment-Host清单头?我希望这个资源文件始终在我的捆绑包中运行的所有捆绑包的类路径中可见,即使那些尚不存在的捆绑包,但将来可能会添加。

编辑:

澄清 - 资源必须被动地提供,即其他bundle应该能够在类路径中找到它,而不是通过引用我的bundle的任何特殊API或服务。

更多背景 - 我的环境有点乱,但我无法控制它,无法改变现有的捆绑包。我可以修改它的唯一方法是添加我自己的包。该环境包含ch.qos.logback.classic bundle的多个副本。当logback启动时,它会在类路径中查找特定的XML配置文件。如果它没有找到它们中的任何一个,那么它的默认行为是使用调试级别将所有内容打印到stdout。此环境以前用于托管GUI应用程序,因此它之前并不重要,但现在我正在尝试调整它,以便我可以在无头模式下使用它的一些功能。因此,现在能够以这样的方式配置它变得非常重要,只有警告和错误才会打印到控制台。

3 个答案:

答案 0 :(得分:1)

您不能以这种方式更改其他包的类路径。

您可以做的是从bundleContext中检索捆绑包的类加载器。您可以将此类加载器提供给另一个包来检索您的资源。

ClassLoader cl = context.getBundle().adapt(BundleWiring.class).getClassLoader();

另一个选择是给另一个包提供资源的URL。

答案 1 :(得分:0)

只要资源在类路径上,任何bundle都可以访问资源,如果它可以获取包含该资源的bundle的类加载器。

例如:

ClassLoader classLoaderOfBundleWithResource = ...
classLoaderOfBundleWithResource.getResourceAsStream( "org/example/resource.xml" );

从维护和API的角度来看,我不建议以这种方式公开资源。 Java类型更适合它。相反,让资源包导出一个类,使客户端能够访问资源的内容。

例如:

public class XmlDocumentProvider {
  public InputStream openDocument() {
    return getClass().getResourceAsStream( "resource.xml" );
  }
}

假设resource.xmlXmlDocumentProvider都位于同一个包中,openDocument将返回资源内容,就像第一个示例中一样。

答案 2 :(得分:0)

一般来说,不,你不能这样做。类空间隔离是OSGi的核心,但是您希望将资源放在一个包的类加载器中,并使其对所有其他包可见。那不是OSGi,它是全局应用程序类路径。

要添加到特定包的内部类路径,唯一可以做的就是编写一个附加到该包的片段。片段可以附加到多个主机包,但如果这些主机具有相同的符号名称,即因为它们是同一个包的不同版本。参见OSGi R6核心规范,第3.14节。

但您确实声明要附加的捆绑包都是ch.qos.logback.classic的副本。如果这意味着它们都具有那个确切的符号名称,那么也许一个片段将会起作用。