I have an OSGI application with Bundles requiring 2 version of IBM MQSeries : 6.0.2 and 7.0.1. We installed the following IBM MQ Bundles (just mentionning the main ones)
com.ibm.mq.osgi.client_6.0.2.5.jarcom.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"
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.*.
No buddy class loading, no Dynamic Class loading.
Now, when Bundle A loads the com.ibm.mq.jms.MQQueueConnectionFactory using
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.
This is NOT the case !?!?? The MQQueueConnectionFactory is loaded from Bundle com.ibm.mq.osgi.client_6.0.2.5 !!
As consequence, Bundle A is using MQ 6.0.2.5..
Setting some Equinox Debug options, I can see the following :
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
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.
Can someone explains the Bundle Class Loader behaviour ?? Why do Equinox wires the bundle A this way ?? And how can I achieve the expected behaviour ??
Bundle B is working as expected...