我面临的问题是“普通”Java,Equinox以及两者之间的通信。我已阅读其他相关问题(here,here和there以及其他网站,例如this one和that one),但找不到一个令人满意的(或工作!)解决方案。
我有一组插件:P1,P2和P3。 P1导出一些由P2使用的类。 P2还导出P3使用的其他类和接口。特别是,P2定义并导出接口MyInterface ,其实现类MyInterfaceImpl实现了MyInterface 。 P3是一个应用程序,因此包含类Launcher实现IApplication 并定义公共对象启动(IApplicationContext)方法。一切都很好。当我从Eclipse运行Launcher作为Eclipse应用程序时,它运行正常。启动器使用 MyInterface 和 MyInterfaceImpl 。
现在,我使用以下(简单)代码以编程方式运行我的应用程序,根据各种帖子,这似乎是运行Equinox / Eclipse应用程序的“好”方式:
void callApplication() {
final String[] args =
new String[] {
"-application",
"Launcher",
... };
EclipseStarter.run(args, null);
}
同样,这段代码工作正常,我可以“看到”我的应用程序运行并产生预期的结果。
现在,我的问题出现了:我想获得一个由我的应用程序构建的 MyInterfaceImpl 实例,在Equinox中运行,回到“外部”Java代码中。我天真的解决方案是在公共对象启动(IApplicationContext)方法中返回此对象,并按如下方式修改我的调用代码:
MyInterface callApplication() {
final String[] args =
new String[] {
"-application",
"Launcher",
... };
return (MyInterface) EclipseStarter.run(args, null);
}
但这种天真的解决方案不起作用。我收到 java.lang.ClassCastException:MyInterfaceImpl无法强制转换为MyInterface 。考虑到它,它是有道理的,因为,在 callApplication()的末尾,我有两个“版本”的对{ MyInterface , MyInterfaceImpl }:来自“外部”Java代码的一个,由JVM类加载器加载,另一个来自Equinox,由Equinox类加载器加载。我修改了我的代码以打印返回对象的类加载器和 MyInterface :
final Object o = EclipseStarter.run(args, null);
System.out.println(o.getClass().getClassLoader());
System.out.println(MyInterface.class.getClassLoader());
而且,事实上,我获得了:
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@7e66458c[P2:1.5.0(id=413)]
sun.misc.Launcher$AppClassLoader@1efc3d2
请注意,返回对象的类加载器据说来自P2,正如预期的那样,因为P2是定义和导出 MyInterface 和 MyInterfaceImpl 。
我尝试了不同的方法来获得{ MyInterface , MyInterfaceImpl }的“兼容”对,但到目前为止没有运气(我总是得到相同的 java。 lang.ClassCastException:MyInterfaceImpl无法强制转换为MyInterface ):
我尝试设置属性-Dorg.osgi.framework.bootdelegation = * -Dorg.osgi.framework.system.packages.extra = MyInterface,MyInterfaceImpl。
我还尝试拦截 start()方法中的 DefaultClassLoader 。
所以,我的问题是:是否有一种方法可以使用Java程序,该程序使用项目中定义的某些类(也是插件并导出这些类)来交换这些类的实例。 Eclipse的一个实例以编程方式启动?谢谢!
答案 0 :(得分:1)
现在,您要做的是首先,删除P2的接口定义并将其添加到原始(非OSGi)JAR中,最好是在一个包中,比如说com.example.api
。然后,添加-Dorg.osgi.framework.system.packages.extra=com.example.api
;还为该包添加P2和P3中的导入。
希望这有帮助。