0

我有一个运行 Equinox 框架的类。现在我想获得一个由框架外的服务返回的对象(在其中一个包中定义)。

不幸的是,我得到一个 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.) 将我的普通类加载器交给捆绑包或 2.) 使用基本数据类型或 3.) 完全以其他方式?

谢谢大家!塞巴斯蒂安

4

1 回答 1

0

所以这个类ParserDTO已经被两个不同的类加载器独立加载:一个在你的包中,一个来自你的“外部”应用程序的应用程序类加载器。您需要确保它仅由一个类加载器加载。

当两个普通包出现这个问题时,关键是确保一个包导出包,另一个包导入它(或者它们都从第三个包导入)。

但是在这种情况下,您是在外部应用程序和 OSGi 内部的包之间进行交互。有一个硬性规定:OSGi 框架不能从 OSGi 中的包中导入包。因此,该包必须存在于外部应用程序中,并通过将其添加到FRAMEWORK_SYSTEMPACKAGES_EXTRA. 还要确保捆绑包导入该包而不是拥有自己的副本。

顺便说一句...您可能想为包选择一个更好的名称,而不仅仅是de!我不认为您是德国唯一的 Java 开发人员,因此您不拥有该命名空间 ;-)

于 2012-07-10T14:44:39.933 回答