简体   繁体   English

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

[英]OSGi/Equinox Classloader uses unexpected Bundle Version

I have an OSGI application with Bundles requiring 2 version of IBM MQSeries : 6.0.2 and 7.0.1. 我有一个带有Bundles的OSGI应用程序,需要2个版本的IBM MQSeries:6.0.2和7.0.1。 We installed the following IBM MQ Bundles (just mentionning the main ones) 我们安装了以下IBM MQ Bundles(仅提到主要的)

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

We defined our 2 Bundles to Require-Bundle as follows (yes I know, we should use import-package ;-)) Bundle A Require-Bundle: com.ibm.msg.client.osgi.wmq;bundle-version="7.0.1" 我们将2个Bundles定义为Require-Bundle,如下所示(是的,我知道,我们应该使用import-package ;-))Bundle A Require-Bundle: com.ibm.msg.client.osgi.wmq;bundle-version="7.0.1"

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

We define additionally org.osgi.framework.bootdelegation=javax.* . 我们另外org.osgi.framework.bootdelegation=javax.* No buddy class loading, no Dynamic Class loading. 没有好友类加载,没有动态类加载。

Now, when Bundle A loads the com.ibm.mq.jms.MQQueueConnectionFactory using 现在,当Bundle A加载com.ibm.mq.jms.MQQueueConnectionFactory

final MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();

I would expect Equinox to load the class from the Bundle com.ibm.msg.client.osgi.wmq_7.0.1.5 . 我希望Equinox从Bundle com.ibm.msg.client.osgi.wmq_7.0.1.5加载该类。 This is NOT the case !?!?? 不是这种情况 !?!?? The MQQueueConnectionFactory is loaded from Bundle com.ibm.mq.osgi.client_6.0.2.5 !! MQQueueConnectionFactory从Bundle com.ibm.mq.osgi.client_6.0.2.5加载!!

As consequence, Bundle A is using MQ 6.0.2.5.. 因此,Bundle A正在使用MQ 6.0.2.5 ..

Setting some Equinox Debug options, I can see the following : 设置一些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
[...]

The "funny" part being that the javax.jms.* classes are loaded from com.ibm.msg.client.osgi.jms.prereq_7.0.1.5 “有趣”部分是从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

IMHO, this has to do with the org.osgi.framework.bootdelegation setting and the fact that the 7.0.1.5 JMS prereq occurs before the 6.0.2.5 one. 恕我直言,这与该做org.osgi.framework.bootdelegation的设定和7.0.1.5 JMS前提条件之前6.0.2.5一个发生的事实。

Can someone explains the Bundle Class Loader behaviour ?? 有人能解释一下Bundle Class Loader的行为吗? Why do Equinox wires the bundle A this way ?? 为什么Equinox以这种方式连接束A? And how can I achieve the expected behaviour ?? 我怎样才能实现预期的行为?

Bundle B is working as expected... 捆绑B按预期工作...

Don't if this is a valid answer but try using this format when defining the dependency in BUndle A version="[7.0.1,7.0.1]" which denotes a strict version range. 如果这是一个有效的答案,请不要尝试在BUndle A version =“[7.0.1,7.0.1]”中定义依赖关系时使用此格式,这表示严格的版本范围。 Also worse case if you're still having issues can you can you load the class directly from the Bundle by doing Platform.getBundle("com.ibm.msg.client.osgi.wmq").loadClass("com.myclass")? 更糟糕的情况是,如果你仍然遇到问题,你可以通过执行Platform.getBundle(“com.ibm.msg.client.osgi.wmq”)直接从Bundle加载类.loadClass(“com.myclass”) ?

I faced similar situation when I use do OSGi related coding in IDE. 当我在IDE中使用OSGi相关编码时,我遇到了类似的情况。 This wiring done by your IDE, is wrong. 这种由您的IDE完成的接线是错误的。 It wires the class from com.ibm.mq.osgi.client_6.0.2.5 while you expect it to wire the same class of com.ibm.msg.client.osgi.wmq_7.0.1.5 . 它连接com.ibm.mq.osgi.client_6.0.2.5的类,而您希望它连接相同的com.ibm.msg.client.osgi.wmq_7.0.1.5类。 The same problem is happening when in the second issue you talked about. 在你谈到的第二期中,同样的问题正在发生。 You can check this by finding com.ibm.mq.jms.MQQueueConnectionFactory class where IDE using it. 您可以通过查找IDE使用它的com.ibm.mq.jms.MQQueueConnectionFactory类来检查这一点。 ( You can use Ctrl + Mouse click to see which version is wired ). (您可以使用Ctrl +鼠标单击以查看所连接的版本)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM