[英]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.