4

IBM MQSeries の 2 つのバージョン (6.0.2 および 7.0.1) を必要とするバンドルを含む OSGI アプリケーションがあります。以下の IBM MQ バンドルをインストールしました (主なもののみを挙げます)。

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

次のように Require-Bundle に 2 つのバンドルを定義しました (はい、知っています。インポート パッケージを使用する必要があります ;-)) バンドル ARequire-Bundle: com.ibm.msg.client.osgi.wmq;bundle-version="7.0.1"

バンドル BRequire-Bundle: com.ibm.mq.osgi.client;bundle-version="[6.0.2,7.0.0)"

さらに を定義しますorg.osgi.framework.bootdelegation=javax.*。バディ クラスのロードも、ダイナミック クラスのロードもありません。

ここで、バンドル A がcom.ibm.mq.jms.MQQueueConnectionFactoryusing をロードするとき

final MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();

Equinox が Bundle からクラスをロードすることを期待しますcom.ibm.msg.client.osgi.wmq_7.0.1.5。これはそうではありません !?!??MQQueueConnectionFactory はバンドルからロードされますcom.ibm.mq.osgi.client_6.0.2.5!!

その結果、バンドル A は MQ 6.0.2.5 を使用しています。

いくつかの Equinox デバッグ オプションを設定すると、次のように表示されます。

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

「面白い」部分は、javax.jms.* クラスがロードされることです。 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、これはorg.osgi.framework.bootdelegation設定と、7.0.1.5 JMS prereq が 6.0.2.5 の前に発生するという事実に関係しています。

誰かが Bundle Class Loader の動作を説明できますか?? Equinox がバンドル A をこのように配線するのはなぜですか?? そして、どうすれば期待される動作を達成できますか??

バンドル B は期待どおりに動作しています...

4

2 に答える 2

0

IDEでOSGi関連のコーディングを行うと、同様の状況に直面しました。IDE によって行われたこの配線は間違っています。com.ibm.mq.osgi.client_6.0.2.5の同じクラスに配線することを期待しているときに、からクラスを配線しますcom.ibm.msg.client.osgi.wmq_7.0.1.5。あなたが話した2番目の問題で同じ問題が発生しています。com.ibm.mq.jms.MQQueueConnectionFactoryIDEがそれを使用しているクラスを見つけることで、これを確認できます。( Ctrl + マウス クリックを使用して、どのバージョンが配線されているかを確認できます)。

于 2012-11-22T04:23:40.933 に答える
0

これが有効な回答である場合はしないでください。厳密なバージョン範囲を示す BUndle A version="[7.0.1,7.0.1]" で依存関係を定義するときに、この形式を使用してみてください。さらに悪いケースとして、まだ問題がある場合は、Platform.getBundle("com.ibm.msg.client.osgi.wmq").loadClass("com.myclass") を実行して、バンドルから直接クラスをロードできます。 ?

于 2012-11-15T20:22:26.083 に答える