この質問は現在、バウンティに寄せられています! この問題を解決する最初の回答が勝ちます。
そのため、最近、OSGI のバンドルが互いに 100% 分離されていないことを発見しました。特に、バンドルがシングルトンを含む共通のバンドルを共有している場合、関連のない 2 つのバンドルがシングルトンを上書きする可能性があります。この問題は、CXF ライブラリで明らかになりました。何が起こっているかの詳細な例を挙げましょう:
バンドル A、B、および共有バンドル CXF がすべて FuseESB ServiceMix (osgi プラットフォーム) に含まれています。CXF の Bus クラスはシングルトンであり、OSGI にはバンドルごとに 1 つのクラスローダーがあるため、CXF を使用する他のすべてのバンドルとこのシングルトンを共有します。したがって、バンドル A とバンドル B に異なるバスを作成することはできないようです。バンドル A は SSL を使用し、バンドル B は SSL を使用すべきではないため、これは重要です。バンドル A とバンドル B が、同じ ServiceMix に一緒にデプロイする必要があること以外は、互いに何の関係もないことを考えると、これはさらに苛立たしいことです。
今、私はしばらくの間(1〜2か月)この問題に直面しており、さまざまな解決策をたくさん読んできました。ただし、問題は、多くのソリューションではソース コードを完全に制御する必要があり、この場合は制御できないことです。私が作成しているバンドル A は、CXF を使用する Xenara と呼ばれる独自のサードパーティの非 osgi ライブラリを使用しています。私の手に負えないビジネス上の理由から、このサードパーティのライブラリを使用する必要があります。幸いなことに、このライブラリが使用する CXF スプリング Bean ファイルにアクセスできます。
この問題を解決するには、バンドル A が CXF の独自の個人用インスタンスを使用できるようにするか、少なくとも他のバンドルと共有されていない CXF バスをインスタンス化できるようにする必要があると思います。私が試したり検討したりした方法は次のとおりです。
CXF をバンドル A に組み込みましたが、残念ながら、クラスローダーはクラスパスを調べる代わりに、バンドル A の外部から CXF をフェッチし続けました。バンドル A の外側を検索する前に、最初にバンドル A 内の CXF を強制的に検索する方法がわかりませんでした。
バンドル A をサービスにする提案がなされました。いくつかの誤解があり、シングルトンは CXF ではなく A にあると考えられていたと思います。とにかく試してみましたが、問題は解決しませんでした。CXF バスは、バンドル A と B の間で共有されていました。
バンドル A が CXF クラスのロードに別のクラスローダーを使用するように、クラスローディングをオーバーライドします。このロジックを完全には理解していませんが、CXF バスと http コンジットを作成するために Spring Bean が使用されていることを考えると、非常にトリッキーになると確信しています。より良いアイデアを得るには、以下の (4) を参照してください。
CXF には、特定のスレッド コンテキストに CXF バスと http-conduit を設定する方法があります。本当にこのソリューションを使用したいのですが、CXF Bean ファイルを同等の Java コードに変換する方法がわかりません。CXF スプリング Bean ファイルを以下に示します。このhttpコンジットを使用してソースコードにアクセスできないことに注意してください。そのため、SOAPService、wsdlにアクセスできないため、このリンクの「Javaコードの使用」に示されている例を使用していませんなど...
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <property name="searchSystemEnvironment" value="true" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> </bean> <cxf:bus> <cxf:outInterceptors> <bean class="com.xenara.messaging.security.IdentityAssertingOutInterceptor" scope="singleton" /> </cxf:outInterceptors> <cxf:features> <wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing"/> </cxf:features> </cxf:bus> <http-conf:conduit name="*.http-conduit"> <http-conf:client AllowChunking="false" Connection="Keep-Alive" /> <http-conf:tlsClientParameters disableCNCheck="true" secureSocketProtocol="TLS"> <sec:keyManagers keyPassword="${javax.net.ssl.keyStorePassword}"> <sec:keyStore type="JKS" password="${javax.net.ssl.keyStorePassword}" file="${javax.net.ssl.keyStore}" /> </sec:keyManagers> <sec:trustManagers> <sec:keyStore type="JKS" password="${javax.net.ssl.trustStorePassword}" file="${javax.net.ssl.trustStore}" /> </sec:trustManagers> <sec:cipherSuitesFilter> <sec:include>SSL_RSA_WITH_3DES_EDE_CBC_SHA</sec:include> ... </sec:cipherSuitesFilter> </http-conf:tlsClientParameters> </http-conf:conduit>