OSGi LinkageError有两个库插件,提供相同的包和类,但版本不同

时间:2016-12-20 14:45:52

标签: java eclipse-plugin osgi eclipse-rcp linkageerror

我有两个库插件,每个库插件具有相同的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的插件时, 它检查首选项值以确定库的哪个版本 用户想要使用。然后Activator使用

bundle.stop() 
bundle.uninstall()

对于不需要的库版本,只留下一个可用的插件来满足 进口包装。到目前为止,一切都按预期运行,并且正确版本 可以毫无错误地使用库。

更改版本时会出现问题。当用户更改库首选项时, 应用程序关闭并要求用户手动重新启动它。这就是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"

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

在不更改首选项的情况下再次重新启动JVM和平台可以解决此问题,但我非常重视 而是找到一个不需要用户重启应用程序两次才能更改的解决方案 图书馆版。是否有其他方法可以解决此问题以避免此链接错误?

1 个答案:

答案 0 :(得分:0)

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

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

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