目的:Eclipse插件開發中,經常要引用第三方包或者是引用其他插件中的類,由于插件開發環境引用類路徑的設置和運行平臺引用類路徑的設置不同,經常導致開發過程OK,一旦運行則出現NoClassDefFoundError的問題。本文的目的是全面分析各種情況下類路徑的設置,以避免這個問題的出現。
說明:Jar包和類路徑實際上是一個概念,比如類com.bbebfe.Test.class打包為test.jar包,添加類引用就直接添加test.jar包。而如果是添加類文件路徑,則添加包目錄的上級目錄,比如lib/com/bbebfe/Test.class,則添加lib文件夾,而不是com文件夾。在此后的例子中都只說明Jar包的形式。
分析:Eclipse插件開發對于Jar包的引用主要有三種原因:
1. 插件引用第三方包(普通的jar包或者類文件,不是插件)。
a) 開發環境引用配置,在prject -> properties -> Java build path中設置。
b) 運行環境引用配置,在plugin manifest編輯器的Runtime選項卡下的classpath中添加tset.jar包的引用(在MANIFEST.MF中表現為Bundle-ClassPath: lib/test.jar, 在plugin.xml表現為<runtime>節下的引用
i. 類文件在lib目錄下,如下的設置導出lib目錄下所有目錄:
<runtime>
<library name="lib/">
<export name="*"/>
</library>
</runtime>
ii. test.jar在lib目錄下:
<runtime>
<library name="lib/test.jar">
<export name="*"/>
</library>
</runtime>
iii. 實際上上面的設置可以簡化為:
<runtime>
<library name="lib/"/>
</runtime>
或者
<runtime>
<library name="lib/test.jar"/>
</runtime>
默認即導出lib目錄下的所有包和jar下的所有包
實際上,執行b)項設置后,會自動執行a)項設置,使開發環境和運行環境同時有效。
2. 插件B引用插件工程A(非Eclipse插件,而是自己另外一個插件項目中的類)
a) 首先必須將A中的B需要的類暴露(export)出來
i. 如果有MANIFEST.MF文件,則表現為plugin manifest編輯器中runtime節的exported packages,通過這里添加需要export的包。在manifest.mf文件中是Export-Package: com.bbebfe
ii. 如果只有plugin.xml,則表現為plugin manifest編輯器中runtime節的library visibility。在plugin.xml文件中表現為
<runtime>
<library>
<export name=”com.bbebfe.*”/>
...
b) 在B插件工程的plugin manifest編輯器中的dependencies選項卡中添加對A插件的引用(這要求運行對話框中的plugins列表的workspace plugins中必須包含A插件)。
c) 如果B工程是一個RCP工程,則必須在product編輯器的configuration選項卡中包含A插件工程。
3. 插件B引用Eclipse插件A的類。
a) Eclipse插件中的類都是Exported,因此這步省略。
b) 在B插件工程的plugin manifest編輯器中的dependencies選項卡中添加對A插件的引用(這要求preferences -> plugin development -> target目標平臺必須包含A插件,且運行對話框的plugins列表中的target platform中必須選中A插件)。
總結:如果B插件引用的A也是一個插件,則A必須出現在B插件的plugin dependencies引用中,而不是其他地方,否則肯定會出現運行時NoClassDefFoundError問題(因此必須在plugin manifest編輯器的dependencies選項卡下進行設置)。而且只需要在這里設置的設置對開發環境和運行環境同時有效)
注意:還有一種情況就是開發環境沒有某個包或者插件,而只在運行環境(target)中存在,此時就必須設置正確的target,然后按照正常程序添加插件引用,但此時已經不能在plugin manifest的dependencies選項卡中設置(因為在開發環境找不到這個plugin),而必須在plugin.xml或MANIFEST.MF文件中手工設置。plugin只要target中存在該插件,則開發和運行也不會有問題。