I have an OSGI application with Bundles that requires 2 versions of IBM MQSeries: 6.0.2 and 7.0.1. We have installed the following IBM MQ Bundles packages (basic mention only)
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 per Requirement-Bundle as follows (yes, I know, we should use import-package ;-)) A Require-Bundle: com.ibm.msg.client.osgi.wmq;bundle-version="7.0.1"
B Package Require-Bundle: com.ibm.mq.osgi.client;bundle-version="[6.0.2,7.0.0)"
We additionally define org.osgi.framework.bootdelegation=javax.* . No buddy class loading, no dynamic class loading.
Now that Bundle A is loading com.ibm.mq.jms.MQQueueConnectionFactory using
final MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
I would expect Equinox to load the class from Bundle com.ibm.msg.client.osgi.wmq_7.0.1.5 . This is not the case!?!?? MQQueueConnectionFactory is loaded from Bundle com.ibm.mq.osgi.client_6.0.2.5 !!
As a result, Bundle A uses MQ 6.0.2.5.
Configuring some Equinox debugging options, I 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 is that the javax.jms classes. * 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 is due to the installation of org.osgi.framework.bootdelegation and the fact that the preliminary version of JMS 7.0.1.5 occurs before version 6.0.2.5.
Can someone explain the behavior of the Bundle class loader? Why does Equinox lay A in this way? And how can I achieve the expected behavior?
Package B works as expected ...