這個問題現在是賞金!解決這個問題的第一個答案獲勝。OSGI CXF單身班加載問題
所以我最近發現OSGI中的bundle並不是100%相互隔離的,特別是當你的bundle共享一個包含單例的bundle時,這可能導致兩個不相關的bundle重寫singleton。這個問題已經在CXF庫中體現出來了。讓我詳細說明發生了什麼:
我們在FuseESB ServiceMix(An osgi平臺)中擁有bundle A,B和共享bundle CXF。 CXF的Bus類是一個單例,由於OSGI每個bundle有一個類加載器,它將與使用CXF的其他bundle共享這個單例。所以我似乎無法爲捆綁包A和捆綁包B創建不同的總線,這一點很重要,因爲捆綁包A應該使用SSL,而捆綁包B不應該使用SSL。這更令人沮喪,因爲捆綁包A和捆綁包B除了必須一起部署在同一個ServiceMix上以外,沒有任何關係。
現在我已經在這個問題一段時間了(1-2個月),我已經讀了很多不同的解決方案。但問題是,很多解決方案都要求我完全控制源代碼,在這種情況下,我不這樣做。 Bundle我創建的是使用一些專有的第三方非osgi庫,名爲Xenara,它使用CXF。出於無法控制的商業原因,我必須使用這個第三方庫。幸運的是,我可以訪問該庫使用的CXF spring bean文件。
我對解決這個問題的猜測是,我需要做一些如何讓包A可以使用自己的CXF個人實例,或者至少使其實例化與其他包不共享的CXF總線。下面是我嘗試或考慮的方法:
我嵌入到CXF一個捆綁可惜的類加載器不停地從包A的外取CXF,而不是看在classpath。從未想出如何強制它在捆綁A中搜索CXF之前,先搜索捆綁A之外的內容。
已提出了使捆綁A成爲服務的建議。我認爲有些誤解,人們認爲這個單身人士是在A而不在CXF中。無論我嘗試過它,它並沒有解決問題。 CXF總線仍然在捆綁包A和B之間共享。
重寫類加載,以便捆綁包A使用不同的類加載器來加載CXF類。我並沒有完全理解這個邏輯,但是我相信,如果使用spring bean來創建CXF總線和http-conduit,那麼將會非常棘手。參見下面的(4)以獲得更好的想法。
在CXF中,有一種方法可以爲給定的線程上下文設置CXF總線和http-conduit。我真的想使用這個解決方案,但我不知道如何將CXF bean文件翻譯成等效的Java代碼。下面提供了CXF spring bean文件。請注意,我無法使用此http-conduit訪問源代碼,這就是爲什麼我沒有使用this link here中的示例在「使用Java代碼」中顯示的原因,因爲我無法訪問SOAPService,wsdl等...
<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>
在這個問題上浪費了大量時間,最終的解決方案是在我們的FuseESB ServiceMix環境之外可悲地運行該程序,並通過ActiveMQ與FuseESB Servicemix通話。 – Thirlan 2012-03-27 16:46:19