我有一个运行Equinox框架的类。现在我想获得一个服务从框架中返回的Object(在其中一个bundle中定义)。
不幸的是,我得到了一个LinkageError,并且不知道如何摆脱它。是否可以让服务将正确的对象返回到非捆绑代码?
以下是完整的故事:
ParserDTOBundle是一个包,用于定义类ParserDTO并导出相应的包。
在另一个包ParserServiceBundle中,我定义了一个名为ParserService的服务。此捆绑包导入ParserDTO的包。 ParserService的函数getDTO()创建一个新的ParserDTO对象并返回它。
现在我创建了另一个启动Equinox框架并从目录中加载两个包的类:
...
EclipseStarter.setInitialProperties(frameworkPropertiesMap);
bundleContext = EclipseStarter.startup(new String[] { "-console", "-dev", "bin" }, null);
bundleContext.installBundle("file:/" + dir + "ParserDTOBundle-0.0.1-SNAPSHOT.jar");
Bundle service = bundleContext.installBundle("file:/" + dir + "ParserServiceBundle-0.0.1-SNAPSHOT.jar");
service.start();
ServiceReference serviceReference = bundleContext.getServiceReference(ParserService.class.getName());
if (serviceReference != null) {
ParserService ps = (ParserService) bundleContext.getService(serviceReference);
if (ps != null) {
ParserDTO dto = ps.getDTO();
System.out.println(dto.getValue());
}
}
上述类是非捆绑Maven项目的一部分。 上述类的运行失败:
Exception in thread "main" java.lang.LinkageError: loader constraint violation: loader (instance of sun/misc/Launcher$AppClassLoader) previously initiated loading for a different type with name "de/ParserDTO"
有趣的是,我在System.out.println而不是之前的行中收到此错误。 我的主类中的ParserDTO类的类加载器明显不同于对象dto的类加载器。
如何获取存储在dto中的信息?这有可能吗? 我是否必须1.)将我的普通类加载器交给bundle或2.)使用基本数据类型或3.)一些完全其他方式??
提前谢谢大家! 塞巴斯蒂安
答案 0 :(得分:0)
所以类ParserDTO
已由两个不同的类加载器独立加载:bundle中的一个,以及来自“outer”应用程序的应用程序类加载器。您需要确保它只由一个类加载器加载。
当两个普通软件包出现此问题时,关键是确保一个软件包导出软件包而另一个软件包导入它(或者它们都从第三个软件包导入它)。
但是在这种情况下,您在外部应用程序和OSGi内部的bundle之间进行交互。有一条硬规则:OSGi框架无法从OSGi中的bundle中导入包。因此,包必须存在于外部应用程序中,并通过将其添加到FRAMEWORK_SYSTEMPACKAGES_EXTRA
从系统包中导出。还要确保捆绑包导入该包而不是拥有自己的副本。
顺便说一句......你可能想要为这个包选择一个比de
更好的名字!我不认为您是德国唯一的Java开发人员,因此您不拥有该命名空间; - )