OSGi / Equinox Classloader使用意外的Bundle版本

时间:2012-09-18 10:30:21

标签: java osgi classloader equinox

我有一个带有Bundles的OSGI应用程序需要2个版本的IBM MQSeries: 6.0.2和7.0.1。 我们安装了以下IBM MQ Bundles(仅提及主要的)

  • com.ibm.mq.osgi.client_6.0.2.5.jar
  • com.ibm.msg.client.osgi.wmq_7.0.1.5.jar

我们将2个Bundles定义为Require-Bundle,如下所示(是的,我知道,我们应该使用import-package ;-)) 捆绑A Require-Bundle: com.ibm.msg.client.osgi.wmq;bundle-version="7.0.1"

捆绑B Require-Bundle: com.ibm.mq.osgi.client;bundle-version="[6.0.2,7.0.0)"

我们另外定义org.osgi.framework.bootdelegation=javax.*。 没有好友类加载,没有动态类加载。

现在,当Bundle A使用

加载com.ibm.mq.jms.MQQueueConnectionFactory
final MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();

我希望Equinox从Bundle com.ibm.msg.client.osgi.wmq_7.0.1.5加载该类。 不是这种情况 !?!?? MQQueueConnectionFactory从Bundle com.ibm.mq.osgi.client_6.0.2.5 !!

加载

因此,Bundle A正在使用MQ 6.0.2.5 ..

设置一些Equinox Debug选项,我可以看到以下内容:

Bundle id 56 == com.ibm.mq.osgi.client_6.0.2.5
Bundle id 53 == com.ibm.msg.client.osgi.jms.prereq_7.0.1.5

[...]
BundleLoader[A_1.1.3].loadBundleClass(com.ibm.mq.jms.MQQueueConnectionFactory)
BundleLoader[com.ibm.mq.osgi.client_6.0.2.5].findLocalClass(com.ibm.mq.jms.MQQueueConnectionFactory)
BundleClassLoader[PATH/org.eclipse.osgi/bundles/56/1/.cp/com.ibm.mq.jar].findClassImpl(com.ibm.mq.jms.MQQueueConnectionFactory)
BundleClassLoader[PATH/org.eclipse.osgi/bundles/56/1/.cp/com.ibm.mqjms.jar].findClassImpl(com.ibm.mq.jms.MQQueueConnectionFactory)
  about to read 11659 bytes from com/ibm/mq/jms/MQQueueConnectionFactory.class
  read 11659 bytes from PATH/org.eclipse.osgi/bundles/56/1/.cp/com.ibm.mqjms.jar/com/ibm/mq/jms/MQQueueConnectionFactory.class
  defining class com.ibm.mq.jms.MQQueueConnectionFactory
[...]

“有趣”部分是从com.ibm.msg.client.osgi.jms.prereq_7.0.1.5加载javax.jms。*类

BundleClassLoader[com.ibm.mq.osgi.client_6.0.2.5].loadClass(javax.jms.QueueConnectionFactory)
BundleLoader[com.ibm.mq.osgi.client_6.0.2.5].loadBundleClass(javax.jms.QueueConnectionFactory)
BundleLoader[com.ibm.msg.client.osgi.jms.prereq_7.0.1.5].findLocalClass(javax.jms.QueueConnectionFactory)
BundleClassLoader[PATH/org.eclipse.osgi/bundles/53/1/.cp/jms.jar].findClassImpl(javax.jms.QueueConnectionFactory)
  about to read 371 bytes from javax/jms/QueueConnectionFactory.class
  read 371 bytes from /opt/fxportal/FXMB/application/configuration/org.eclipse.osgi/bundles/53/1/.cp/jms.jar/javax/jms/QueueConnectionFactory.class
  defining class javax.jms.QueueConnectionFactory
BundleLoader[com.ibm.msg.client.osgi.jms.prereq_7.0.1.5] found local class javax.jms.QueueConnectionFactory

恕我直言,这与org.osgi.framework.bootdelegation设置以及7.0.1.5 JMS先决条件发生在6.0.2.5之前的事实有关。

有人能解释一下Bundle Class Loader的行为吗?为什么Equinox以这种方式连接束A?我怎样才能达到预期的行为?

捆绑包B按预期工作......

2 个答案:

答案 0 :(得分:0)

如果这是一个有效的答案,请不要尝试在BUndle A version =“[7.0.1,7.0.1]”中定义依赖关系时使用此格式,这表示严格的版本范围。更糟糕的情况是,如果你仍然遇到问题,你可以通过执行Platform.getBundle(“com.ibm.msg.client.osgi.wmq”)直接从Bundle加载类.loadClass(“com.myclass”) ?

答案 1 :(得分:0)

当我在IDE中使用OSGi相关编码时,我遇到了类似的情况。这种由您的IDE完成的接线是错误的。它将类从com.ibm.mq.osgi.client_6.0.2.5连接起来,而您希望它连接同一类com.ibm.msg.client.osgi.wmq_7.0.1.5。在你谈到的第二期中,同样的问题正在发生。您可以通过查找IDE使用它的com.ibm.mq.jms.MQQueueConnectionFactory类来检查这一点。 (您可以使用Ctrl +鼠标单击以查看所连接的版本)。