我有包 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 和其他)都停止并重新启动。
问问题
196 次
1 回答
0
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 服务,它可以工作。在 bundle A 中获取 bundle B。使用bundleB.loadClass()加载类类型并将其强制转换为位于B.API中的接口。
于 2014-09-16T15:04:02.037 回答