Eclipse Virgo - 类加载器在bundle重载后返回旧类

时间:2014-09-16 14:19:48

标签: eclipse osgi classloader eclipse-virgo

我有bundle A和bundle B. Bundle B从bundle A和bundle B导入包,Eclipse-RegisterBuddy设置为bundle A. Bundle A加载由B反射(Class.forName)由B导出的类。当重新部署bundle B时,bundle A仍旧引用来自旧版本B的classloader,因此Class.forName从B返回旧类版本。这导致当在B中创建参数并且传递参数时,从A调用Class.isInstance返回false到A中的方法 有没有办法刷新A中的类加载器才能从B返回新版本的类?可以从Virgo控制台调用bundle refresh A命令,这解决了这个问题,但是这个刷新会导致所有相关的bundle(B和其他)被停止并再次启动。这不适用于我们的应用程序,因为捆绑包B和从A导入包的其他包是长时间运行的批处理作业,无法停止。

1 个答案:

答案 0 :(得分:0)

Class.forName()是OSGi中的反模式,请勿使用:http://wiki.osgi.org/wiki/Avoid_Classloader_Hacks

您应该为您的班级创建一个界面。界面应稳定。您应该将此界面放入单独的捆绑包,例如 B.API 。在捆绑A中,您应该使用此接口而不是类。将稳定接口放在单独的捆绑包中后,刷新B不会导致依赖捆绑包的重新启动。您可以通过多种方式获取所需的实例:

选项1

您应该考虑OSGi服务及其生命周期。 Bundle B应该注册捆绑A使用的OSGi服务。您可以编写ServiceTracker或使用Declarative Services来获取服务。

选项2

您应该选择选项1.我不建议选项2,但如果您因某些原因不想使用OSGi服务,它可以工作。在bundle A中获取bundle B.使用bundleB.loadClass()加载类类型并将其转换为位于 B.API 中的接口。