【问题标题】:How to get a bundle-object returned by a service out of the Equinox framework - java.lang.LinkageError如何从 Equinox 框架中获取服务返回的捆绑对象 - java.lang.LinkageError
【发布时间】:2012-07-09 22:11:46
【问题描述】:

我有一个运行 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.) 完全以其他方式??

提前谢谢大家! 塞巴斯蒂安

【问题讨论】:

    标签: java osgi classloader bundle equinox


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 谢谢!这就是问题所在。使用 FRAMEWORK_SYSTEMPACKAGES_EXTRA 将 DTO 的包设置到框架属性映射后,它可以正常工作。我总是忽略系统捆绑包,但现在我想我会仔细看看它的设置。再次感谢您。
    • 我总是减少变量名、类名和命名空间,以使所有内容更具可读性;)
    • 太棒了。当您在 OSGi 和外部应用程序之间进行交互时,您不能忽略系统包,因为这正是交互发生的地方。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    相关资源
    最近更新 更多