0

我在一个普通的 Java 应用程序中使用了两个 OSGi 框架。两个框架都从共享目录加载包。

在一个包中,我从资源中加载一个文件。我尝试了不同的方法,例如

this.getClass().getClassLoader().getResourceAsStream(...)
FrameworkUtil.getBundle(XXX.class).getEntry(...)
FrameworkUtil.getBundle(XXX.class).getResource(...)

但不管我使用哪个命令,一开始都可以正常工作。但是,在两个框架中的几个安装和卸载步骤之后。返回的 InputStream 为空。

如果只使用一个 OSGi 框架,我也可以正常工作。

调试了一下,发现Bundle a got with

FrameworkUtil.getBundle(XXX.class)

指向正确的 jar 文件,但是当我在 Bundle 的 BundleData 中查找引用的包文件时,它引用了另一个包的包文件。捆绑文件是 OSGi 框架(在我的例子中是 Equinox)的临时文件,例如可以在本地 Maven 存储库中找到:

.m2\repository\org\eclipse\osgi\org.eclipse.osgi\3.6.0.v20100517\configuration\org.eclipse.osgi\bundles\29\1

任何人都知道这里可能出了什么问题?

4

2 回答 2

0

执行资源加载的代码是否从框架中的包运行?还是来自框架外的代码?

每次解析捆绑包时,它都会获得一个新的类加载器。当捆绑包无法解析时(例如卸载时),其类加载器将被销毁并与后备存储断开连接(例如捆绑包 jar 文件)。因此,您使用的 Class 对象可能不再有用,因为它是从现已销毁的类加载器加载的。

请记住,在运行时,类对象是唯一的类文件,类加载器对。

于 2012-09-12T15:51:03.407 回答
0

两个框架都使用相同的目录来保存包的配置。似乎一个框架偶然覆盖了另一个框架的捆绑文件/配置文件。

当捆绑包尝试访问其资源时,它会查找配置文件。如果此文件已被覆盖,则资源文件的条目不再可用,从而导致值为 null 的 InputStream。

为了避免这类问题,可以为每个框架设置不同的配置目录,例如通过

Map<String, String> frameworkPropertiesMap = new HashMap<String, String>();
frameworkPropertiesMap.put("osgi.configuration.area", "@user.home/osgi-framework-configuration-" + numberOfFramework);
framework = getFrameworkFactory().newFramework(frameworkPropertiesMap);
framework.start();
于 2012-09-13T07:09:42.683 回答