【问题标题】:Eclipse Virgo - classloader returns old class after bundle reloadEclipse Virgo - 捆绑重新加载后类加载器返回旧类
【发布时间】:2014-11-10 08:22:42
【问题描述】:

我有包 A 和包 B。包 B 从包 A 导入包,包 B 将 Eclipse-RegisterBuddy 设置为包 A。包 A 加载由 B 通过 Java 反射 (Class.forName) 导出的类。重新部署bundle B时,bundle A仍然引用旧版本B的类加载器,因此Class.forName从B返回旧类版本。这导致当参数是在B中创建并传递的实例时,从A调用Class.isInstance返回false到 A 中的方法。 有什么方法可以刷新 A 中的类加载器以便能够从 B 返回新版本的类?可以从 Virgo 控制台调用 bundle refresh A 命令,这解决了这个问题,但是这个刷新会导致所有依赖的 bundle(B 和其他)都停止并重新启动。这不适合我们的应用程序,因为 bundle B 和其他从 A 导入包的包是长时间运行的批处理作业,无法停止。

【问题讨论】:

    标签: eclipse osgi classloader eclipse-virgo


    【解决方案1】:

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

    你应该为你的类创建一个接口。界面应该稳定。您应该将此接口放入单独的包中,如B.API。在包 A 中,您应该使用此接口,而不是类。将稳定接口放在单独的包中后,刷新 B 不会导致依赖包的重新启动。您有多种选择来获取所需的实例:

    选项 1

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

    选项 2

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-12
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 2021-07-21
      • 1970-01-01
      相关资源
      最近更新 更多