1. 程式人生 > >osgi中第三方bundle的問題

osgi中第三方bundle的問題

post sdn face del spec 指定 pool for symbol

2015年1月20日寫到:

OSGi常見問題總結 :http://blog.csdn.net/ostrichmyself/article/details/7515653
IBM的另一個場景:http://www-01.ibm.com/support/docview.wss?uid=swg21568564
一個很多的文檔:http://www.bouncycastle.org/specifications.html


頭疼的問題:
銀聯給了個jar包,upacp_sdk-1.0.0.jar 此包用於簽名,加解密。
在將這個jar包放到我們的程序裏後,由於upacp_sdk-1.0.0本身引用了其他的類庫(包括log4j-1.2.17,bcprov-jdk16-1.45,commons-codec-1.6,commons-lang-2.5,slf4j-api-1.5.11,slf4j-log4j12-1.5.11等),所以報錯。但是我們的框架也有log4j,bcprov,commons等jar包,所以想不引用它的jar包,而用我們程序的jar包,但是楞是不能成功。upacp_sdk-1.0.0對log4j的引用是用maven引用的,指定了版本了(不知到maven對於指定的版本,是只能是那個版本,還是只要高於那個版本就可以?)。但是對於bcprov-jdk16-1.45這個jar包卻是完全一樣的(我們叫做bcprov-jdk16-145,放在了jdk下邊),但是仍然不行。
做實驗,新建一個普通的project,用到upacp_sdk-1.0.0.jar,將upacp_sdk-1.0.0.jar 的依賴包都放在lib下,只把他的bcprov-jdk16-1.45去掉,用jdk的。這樣就可以調用成功。
但是新建一個plugin的project,在這麽做的話,就說找不到:java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider。
懷疑,因為bcprov-jdk16-1.45並不是java原生的jar包(我猜的,1是因為,這個東西是在大家遇到問題之後從網上找解決方案,放到了jdk下邊的;2是因為它的包名字是org.bouncycastle.jce.provider),在osgi工作時,bundle類加載器是分角色的(父類加載器,框架類加載器,java平臺提供的應用程序加載器),我們用到bcprov-jdk16-1.45,就需要類加載器把這個bundle加載進來,但是由於bundle本身的類加載器並不能搜索到這個jar包(因為這個jar包在jdk下,而不在這個bundle裏邊),而應用程序加載器不認為這個jar包是原生的,所以不加載(應用程序加載器加載java.*開頭的package)。那麽用到這個類的時候就找不到。
以上僅僅是猜測,覺得是這個原因,但是對於好多原理還不清楚。不敢斷言。尤其是我們的框架也用到了這個jar包,並且也沒在lib下引用,也沒在*.MF文件裏引用,為什麽我們的程序可以正常運行?當然,即便把jdk下的bcprov-jdk16-145去掉後,我們的程序報的錯也不一樣,我們報的錯是missing。

在北京銀行做的時候,也有一個關於加解密的東西,在eclipse裏就可以正常運行,但是放到linux上就報錯,說找不到什麽東西。檢查之後,jdk裏也有,就是把包在import裏引用了一下。

由於時間問題,可能不能繼續研究這個問題了。如果需要我們這邊調用銀聯的jar包來加密的話,給出解決方案:
新建立一個bundle,這個bundle引用upacp_sdk-1.0.0.jar(並且將其所有的依賴包加進來),進行簽名的工作。別的bundle用的簽名的功能時直接引用這個bundle的服務。這樣將這個bundle的jar包,與我們的jar包隔離,以免互相影響。尤其是,jar包相近,版本不同。

如果有時間調查的話,調查以下幾方面:
委派名單
org.osgi.framework.bootdelegation=sun.*,com.sun.*
添加隱式導出Package 的參數
org.osgi.framework.system.packages=javax.crypto.interfaces
java底層類和虛擬機怎麽加載
執行環境


2015年1月20日22:57:29
http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fbuddy_loading.html 這篇文章解決了簽名的問題。
Third party libraries and classloading
Because OSGi makes use of multiple classloaders, the transparent usage of extensible / configurable third party libraries in eclipse requires the usage of an eclipse specific mechanism called "buddy loading". This mechanism allows a bundle to indicate that it needs assistance to load classes or resources when it can not find them among its prerequisites. Note that we call "extensible libraries", libraries that needs to see classes or resources provided by user code (for example log4j logger mechanism, hibernate,...).

To indicate its need for buddy loading, a bundle must modify its manifest and add the following header:

Eclipse-BuddyPolicy: <value>

<value> refers to the policy used to look for the classes. Here are the supported policies:

registered - indicates that the buddy mechanism will consult bundles that have been registered to it. Bundle willing to be registered to a particular bundle add in their manifest: "Eclipse-RegisterBuddy: <bundleSymbolicName>";
dependent - indicates that the classes/resources will be looked up transitively in all the dependent of the bundle;
global - indicates that the classes/resources will be looked up in the global pool of exported package;
app - indicates that the application classloader will be consulted;
ext - indicates that the extensiont classloader will be consulted;
boot - indicates that the boot classloader will be consulted.


其中:app,ext可以,其他的不行。

下面是“深入探討 Java 類加載器”
http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html#toggle
下面是“戎馬一生”寫的“bootdelegation vs. org.osgi.framework.system.packages.ex”
http://rongmayisheng.com/post/bootdelegation-vs-org-osgi-framework-system-packages-extra

osgi中第三方bundle的問題