简体   繁体   English

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

[英]OSGi LinkageError with two library plugins providing the same packages and classes, but different versions

I have two library plugins, each of the same library that have the same API, but different versions 我有两个库插件,每个库插件具有相同的API,但版本不同

One of the library plugins has the following in the MANIFEST.MF: 库插件之一在MANIFEST.MF中具有以下内容:

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

The second library plugin has the following defined in the MANIFEST.MF: 第二个库插件在MANIFEST.MF中具有以下定义:

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

The plugin that uses this API has the following defined in the MANIFEST.MF: 使用此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]"

When the plugin that is using Import-Package is activated, it checks a preference value to determine which version of the library the user would like to use. 激活使用导入包的插件时,它将检查首选项值以确定用户要使用哪个版本的库。 The Activator then uses 然后,激活器使用

bundle.stop() 
bundle.uninstall()

for the library version that is NOT wanted, leaving only the one plugin available to satisfy the Import-Package. 对于不需要的库版本,仅保留一个插件来满足Import-Package。 Up to this point, everything functions as expected and the correct version of the library can be used without error. 至此,所有功能均按预期运行,并且可以正确使用库的正确版本。

The problem comes in when changing versions. 更改版本时出现问题。 When a user changes the library preference, currently, the application shuts down and asks the user to restart it manually. 当前,当用户更改库首选项时,应用程序将关闭并要求用户手动重新启动它。 This guaruntees that the JVM and platform both restart so that I can programmatically stop and uninstall the other version of the plugin. 这样可以确保JVM和平台都重新启动,以便我可以以编程方式停止和卸载该插件的其他版本。 However, when the library consumer plugin attempts to invoke the remaining installed version of the library plugin, the following exception is thrown: 但是,当库使用者插件尝试调用库插件的其余已安装版本时,将引发以下异常:

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"

There was a similar problem here , but the solution seemed to be rename some of the packages to just avoid the issue. 有一个类似的问题在这里 ,但解决的办法似乎是重命名一些包,只是回避问题。 This solution will not work for me as the entire point is them having the exact same API and just changing out the underlying library version. 该解决方案对我而言不起作用,因为整个观点是它们具有完全相同的API,只是更改了底层库的版本。

Restarting the JVM and Platform again without changing the preference fixes this issue, but I'd much rather find a solution that doesn't require users to restart the application two times to change a library version. 在不更改首选项的情况下再次重新启动JVM和平台可解决此问题,但我宁愿找到一种解决方案,该解决方案不需要用户两次重新启动应用程序即可更改库版本。 Is there another way to solve this problem to avoid this linkage error? 还有另一种解决此问题的方法来避免此链接错误?

It sounds like the classloader using the other library is still active. 听起来使用其他库的类加载器仍处于活动状态。

You have to make sure the bundle using the library is not holding any references to objects and classes when it is stopped. 您必须确保使用该库的捆绑软件在停止时不保存对对象和类的任何引用。 Only then can the bundle classloader be cleaned up. 只有这样,bundle类加载器才能被清理。

Additionally you have to refresh all bundles using the library. 此外,您必须使用该库刷新所有捆绑软件。 This will rewire them to the new library. 这会将它们重新连接到新库。

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

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