【问题标题】:OSGI Classloading & Object SharingOSGI 类加载和对象共享
【发布时间】:2014-04-29 14:37:46
【问题描述】:

好的。所以我知道用ClassloaderA实例化的类不能直接传给ClassloaderB,因为在JVM眼里,对象的“类”在不同的类加载器中会不一样。

我也知道序列化对象以将其发送到 ClassloaderB 会很慢,而且我看不到使用这种方法的 OSGi 容器。如果我有一个将服务导出到 BundleB(导入服务)的 bundleA 并且调用了返回 ObjectA 的方法“serviceMethod()”,那么 ObjectA 如何从 BundleA 传递到 BundleB?

谢谢!

【问题讨论】:

    标签: java osgi classloader


    【解决方案1】:

    如果你在两个包中导入同一个包,那么通常两个包都会连接到这个包的同一个类加载器。 假设我们有 bundle A 提供服务接口和相关的类,bundle B 为服务提供内部服务实现,bundle C 使用服务。

    Bundle B 将导入服务接口和其他带有服务类的包。因此,如果它对导入包中的类执行新操作,那么它将触发他自己的类加载器(B)来加载该类。这个类加载器将在包被导入时委托给类加载器 A。因此,类加载器 A 将有效地加载服务类。

    这同样适用于包 C,因为公共类也被导入加载将委托给类加载器 A。因此两个包将能够使用服务接口和导入的类进行通信。

    顺便说一句。您甚至可以将未知的对象传输到包 C。例如,包 B 可以创建一个私有类并将其作为“对象”在服务中返回。然后包 C 仍然可以与该类一起使用并对其使用反射。所以不需要编组。

    OSGi 类加载可能出错的唯一情况是,例如 bundle C 嵌入了服务接口 jar A。然后这些包将使用类加载器 C 加载。因此它们将与 bundle B 已知的不同。所以留下尽可能远离嵌入。

    【讨论】:

    • 我提出这个问题背后的驱动力之一是花了一整个下午试图弄清楚为什么 Karaf 告诉我我的 ActiveMQConnectionFactory 无法转换为 ConnectionFactory。为了快速启动和运行,我构建了一个 uber-bundle,包括运行 ActiveMQ 所需的所有依赖项......不幸的是,它还包括 javax.jms.ConnectionFactory 类。因为它是在 ActiveMQ jar 中提供的,但带有 ActiveMQConnectionFactory 实例的包正在使用我包装的 javax.jms 包,所以它将它们视为两个不同的类。
    • 是的 .. 在很多情况下使用 uber bundle 方法时会发生这种情况。幸运的是,在您的情况下,这很容易。 ActiveMQ 已经作为 karaf 功能提供。尝试功能:chooseurl activemq 5.9.0 。然后,您可以安装 activemq 功能。我在我的一个教程中使用它:liquid-reality.de/display/liquid/2012/01/03/…
    【解决方案2】:

    BundleB 关联的类加载器被连接到从BundleA 加载类,因为BundleA 被定义为依赖项。因此BundleB 可以访问从BundleA 返回的对象类。

    见:

    【讨论】:

    • 我完全理解“类”可以被加载和实例化——这部分是有道理的,因为你实际上只是从另一个包中拉入包。我描述的情况不同。我说的是 BundleA 拥有的服务。服务本身被导出并且仍然存在于 BundleA 中。当 BundleB 要求 BundleA 调用方法“serviceMethod()”并获取返回的对象时,该对象如何到达 BundleB?
    • 一个“服务”必须有一个接口,对吧?该接口必须对两个捆绑包都可用,不是吗?这意味着构成该服务接口的类由两个类加载器加载。
    • 我认为两个不同类加载器中的类被视为不同。是不是因为两个类加载器都指向同一个 jar 文件,所以它们被视为同一个类?
    • 我正在寻找@java 类加载基础知识。我看到了这个:“保留这个哈希表很重要,因为每次被要求时都必须为相同的类名返回相同的类对象引用。否则系统会认为有两个不同的类相同的名称,并且每当您在它们之间分配对象引用时都会抛出 ClassCastException。“我的猜测是 OSGI 的捆绑类加载器在导出/导入时使用相同的对象引用?
    • 类加载器有层次结构。公共依赖项放在树的底部。有关详细信息,请参阅这些出色的幻灯片slideshare.net/martinlippert/…
    猜你喜欢
    • 2012-08-18
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    • 2018-09-17
    • 2016-04-03
    • 2015-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多