简体   繁体   English

访问OSGi捆绑包资源时发生NullPointerException

[英]NullPointerException when accessing OSGi bundle resources

I am using two OSGi frameworks within a plain Java application. 我在一个普通的Java应用程序中使用了两个OSGi框架。 Both frameworks load bundles from a shared directory. 这两个框架都从共享目录加载捆绑包。

In one bundle, I load a file from the resources. 在一个捆绑包中,我从资源中加载文件。 I tried different ways eg 我尝试了不同的方法,例如

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

But it doesn't matter which of the commands I use, it all works fine at the beginning. 但是我使用哪个命令都没有关系,一开始一切都很好。 However, after several install and uninstall steps in both frameworks. 但是,在两个框架中都执行了几个安装和卸载步骤之后。 The returned InputStream is null. 返回的InputStream为null。

I also works fine if use just one OSGi framework. 如果仅使用一个OSGi框架,我也可以正常工作。

After debugging a little, I found that the Bundle a got with 调试了一点之后,我发现Bundle有了

FrameworkUtil.getBundle(XXX.class)

is pointing to the correct jar-file BUT when I look for the referenced bundlefile in the BundleData of the Bundle, it references the bundlefile of another bundle. 当我在Bundle的BundleData中查找引用的bundlefile时,它指向正确的jar文件,但它引用了另一个bundle的bundlefile。 The bundlefiles are temporary files of the OSGi framework (Equinox in my case), that can be found for example in the local Maven repository: 捆绑文件是OSGi框架(在我的情况下为Equinox)的临时文件,例如,可以在本地Maven存储库中找到:

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

Anyone has an idea what could be wrong here? 任何人都知道这里可能有什么问题吗?

Is the code doing the resource loading running from a bundle in the framework? 进行资源加载的代码是否从框架中的捆绑运行? Or from code outside the framework? 还是来自框架之外的代码?

Each time a bundle is resolved, it gets a new class loader. 每次解析包时,它都会获得一个新的类加载器。 When the bundle becomes unresolved (like when it is uninstalled), its class loader is destroyed and disconnected from the backing store (eg bundle jar file). 当捆绑软件变得无法解析时(例如卸载时),其类加载器将被破坏并与后备存储断开连接(例如捆绑软件jar文件)。 So the Class object you use may no longer be useful since it was loaded from a now destroyed class loader. 因此,您使用的Class对象可能不再有用,因为它是从现已销毁的类加载器加载的。

Remember, at runtime a Class object is unique by the class file, class loader pair. 请记住,在运行时,类对象是类文件(类加载器对)唯一的。

Both frameworks use the same directory to save the configurations of the bundles. 这两个框架使用相同的目录来保存捆绑软件的配置。 It seems by accident one framework overwrites the bundlefile/configuration file of the other framework. 偶然地,一个框架覆盖了另一个框架的bundlefile /配置文件。

When the bundle tries to access its resources it looks up the configuration file. 当捆绑软件尝试访问其资源时,它将查找配置文件。 If this file has been overwriten, the entry for the resource file is not available anymore, leading to an InputStream with value null. 如果该文件已被自动覆盖,为资源文件中的条目已不存在,导致有null值的InputStream。

To avoid these kind of problems, it is possible to set the configuration directoy for each framework differently, eg by 为避免此类问题,可以为每个框架设置不同的配置目录,例如

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM