0

我有两个库插件,每个库都具有相同的 API,但版本不同

其中一个库插件在 MANIFEST.MF 中有以下内容:

Export-Package: com.package1.packagename1;version=1.0.0,
com.package2.packagename2;version=1.0.0

第二个库插件在 MANIFEST.MF 中定义了以下内容:

Export-Package: com.package1.packagename1;version=1.1.0,
com.package2.packagename2;version=1.1.0

使用此 API 的插件在 MANIFEST.MF 中定义了以下内容:

Import-Package: com.package1.packagename1;version="[1.0.0,1.1.0]",
com.package2.packagename2;version="[1.0.0,1.1.0]"

当使用 Import-Package 的插件被激活时,它会检查首选项值以确定用户想要使用哪个版本的库。然后激活器使用

bundle.stop() 
bundle.uninstall()

对于不需要的库版本,只留下一个可用的插件来满足 Import-Package。到目前为止,一切都按预期运行,并且可以使用正确版本的库而不会出错。

更改版本时出现问题。当前,当用户更改库首选项时,应用程序会关闭并要求用户手动重新启动它。这保证了 JVM 和平台都重新启动,以便我可以以编程方式停止和卸载插件的其他版本。但是,当库消费者插件尝试调用库插件的剩余已安装版本时,会抛出以下异常:

java.lang.LinkageError: loader constraint violation: loader (instance of
org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) previously
initiated loading for a different type with name "com/package1/packagename1/ClassName"

这里有一个类似的问题,但解决方案似乎是重命名一些包以避免这个问题。这个解决方案对我不起作用,因为它们具有完全相同的 API 并且只是更改了底层库版本。

在不更改首选项的情况下再次重新启动 JVM 和平台可以解决此问题,但我更愿意找到一个不需要用户重新启动应用程序两次以更改库版本的解决方案。是否有另一种方法可以解决此问题以避免此链接错误?

4

1 回答 1

0

听起来使用其他库的类加载器仍然处于活动状态。

您必须确保使用该库的包在停止时不包含对对象和类的任何引用。只有这样才能清理捆绑类加载器。

此外,您必须使用该库刷新所有捆绑包。这会将它们重新连接到新库。

于 2016-12-20T15:10:21.927 回答