1. 程式人生 > >解決OSGI環境第三方包的NoClassDefFoundError

解決OSGI環境第三方包的NoClassDefFoundError

總結了一下:

1、把第三方包的class檔案改造為一個bundle,export所有的package

2、使用了eclipse的equinox實現啟動所有bundle

3、在eclipse環境下啟動都正常,但是放在命令行(windows/linux都一樣)啟動,都失敗,即出現:

Exception in thread 'Thread-1' java.lang.NoClassDefFoundError: javax/naming/NamingException
  at java.lang.Class.forName0(Native Method)
  at java.lang.Class.forName(Class.java:169)
  at com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser.class$(SqlMapConfigParser.java

4、經過比較兩者的執行

環境,發現關鍵差別在於java.syspath和osgi launcher不同,但是也無法改變。

5、經過javaeye和osgi china groups的搜尋,發現了一個國外的帖子(共享一下):

Option 1: "DynamicImport-Package: *" to the manifest of your bundle. This is one possible pure OSGi solution and should do what you want.

Option 2: If you are using Equinox as OSGi implementation you could also take a look at the Buddy-Loading mechanism:
http://help.eclipse.org/help33/t ... /buddy_loading.html


6、解決方法總結:在第三方包的class載入其他的類,而這些類又不在當前的bundle,可能出現這個異常,只要在Manifest.mf檔案加入DynamicImport-Package: *,或者使用eclipse的buddy loading機制(還沒有試驗)可以解決問題。

總之,osgi的好處很多,但是缺點(不方便的地方)也很明顯,就是classpath(classloader)機制,正因為如此,我才放棄了spring。但是spring+osgi是大勢所趨,兩者的DI很相似,OSGI的DS用起來非常像spring的配置
檔案。等有空研究一下兩者的結合。