Java 访问OSGi捆绑资源时出现NullPointerException

Java 访问OSGi捆绑资源时出现NullPointerException,java,osgi,equinox,apache-felix,Java,Osgi,Equinox,Apache Felix,我在一个普通Java应用程序中使用了两个OSGi框架。两个框架都从共享目录加载捆绑包 在一个包中,我从资源中加载了一个文件。我试过不同的方法 this.getClass().getClassLoader().getResourceAsStream(...) FrameworkUtil.getBundle(XXX.class).getEntry(...) FrameworkUtil.getBundle(XXX.class).getResource(...) 但不管我使用哪一个命令,一开始都可以正

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

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

this.getClass().getClassLoader().getResourceAsStream(...)
FrameworkUtil.getBundle(XXX.class).getEntry(...)
FrameworkUtil.getBundle(XXX.class).getResource(...)
但不管我使用哪一个命令,一开始都可以正常工作。但是,在两个框架中执行了几个安装和卸载步骤之后。返回的InputStream为空

如果只使用一个OSGi框架,我也可以很好地工作

在调试了一点之后,我发现包a与

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

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


有人知道这里可能出了什么问题吗?

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

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


请记住,在运行时,类对象对于类文件、类装入器对来说是唯一的。

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

当捆绑包尝试访问其资源时,它会查找配置文件。如果此文件已被覆盖,则资源文件的条目将不再可用,从而导致值为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();
Map frameworkPropertiesMap=newhashmap();
frameworkPropertiesMap.put(“osgi.configuration.area”,“@user.home/osgi-framework-configuration-”+numberOfFramework);
framework=getFrameworkFactory().newFramework(frameworkPropertiesMap);
framework.start();

我确实从捆绑包代码本身加载了捆绑包的资源。因此,在访问资源时,该捆绑包被解析并具有有效的类加载器。问题源于OSGi创建的配置文件。在每个配置文件中,OSGi保存资源的文件名以及其他内容。如果两个框架使用相同的配置目录,则可能会覆盖其配置文件,从而导致缺少资源条目。另见我对问题的回答。无论如何,感谢您考虑可能的原因!当运行多个框架实例时,需要为每个框架使用不同的存储位置。请参见设置org.osgi.framework.storage以及osgi.configuration.area