Eclipse插件開發 RCP生成jar包後獲取jar包中的Plugin/Bundle文件資源——以FreeMarker爲例

       在進行Eclipse插件開發時,有一種應用場景是,需要在插件項目中設置存放有例如配置文件、模板文件的資源文件夾。本文介紹的問題是,插件項目打包發佈後,無法訪問資源文件夾中的資源文件。

       問題重現:

       在插件項目的根目錄下有模板資源文件夾,需要在插件運行時訪問這些資源。在插件開發中,通過"Run as -- Eclipse Application"方式測試插件,可以正常訪問,但是生成jar包後發佈運行,卻無法定位到這些資源文件(表現爲,指向該資源文件的URL對象爲空)。

       問題代碼(目的是插環件境中定位FreeMarker模板文件位置,本例中模板文件路徑爲Project_HOME(插件工程根目錄)/resources/*.ftl):

cfg = new Configuration();
URL url = Activator.getDefault().getBundle().getResource("resources");
//log.info("resources url: " + url);  // 測試代碼,其中log爲private static Logger log = LoggerFactory.getLogger(FreeMarkerUtil.class);
//log.info("resources path: " + url.toString());
String resourcesPath = FileLocator.toFileURL(url).getPath();
File resourcesDir = new File(resourcesPath);
cfg.setDirectoryForTemplateLoading(resourcesDir);  // FreeMarker定位資源的方法隨應用場景不同調用不同API,詳見FreeMarker手冊
Template template = cfg.getTemplate(templateName, "UTF-8");  // templateName爲相對於resources路徑,如templateName="a.ftl",則其路徑爲Project_HOME/resources/a.ftl

問題原因解析:

       Eclipse API通過這些資源相對於Plugin/Bundle的路徑,獲取這些資源的絕對路徑的方法。Eclipse API通過IBundle接口獲取位於在Bundle文件目錄中的資源,也就是說,必須將資源路徑配置到Bundle的類加載路徑中,才能保證Bundle能夠定位、訪問這些資源。有關Eclipse API、Bundle等概念和插件資源等相關知識的深入內容,推薦閱讀:http://blog.csdn.net/soszou/article/details/8034482


      本文問題解決方案:

      1)項目開發中的資源文件夾如圖:

wKiom1RHz1vA9yvPAAAlkRxpmGw766.jpg

          插件Classpath配置如圖:

wKiom1RHzbGSWYunAAGKrWTNsms996.jpg

         以"Run as -- Eclipse Application"方式測試插件時可以正常訪問,但打包發佈後,運行時得到的資源URL如圖:

wKioL1RHz7iDDYO5AACCGeIJ3Dk163.jpg

        2)解決方法:打開MANIFEST.MF的編輯器,在"Runtime"編輯頁,將資源文件夾(本文中爲"resources")配置進入Classpath,如圖:

wKiom1RHzhrAnsgCAAJO8b3pffQ874.jpg

        結果爲:

wKioL1RHzpDA8ImwAAFwOuPWjiA367.jpg

        添加後,可以發現"resources"文件夾的圖標發生改變,如圖:

wKiom1RH0NHh08eUAAAkVVvNfBo764.jpg

       打包發佈後,運行時得到的資源URL如圖:

wKiom1RHzpSgWjq9AAD6V3trytg491.jpg

        3)結論:

        必須將資源路徑配置到Bundle的類加載路徑中,才能保證Bundle能夠定位、訪問這些資源。其實可以通過插件加載icons目錄下的圖片文件的機制,聯想到其他資源文件的加載。在Eclipse API中可以通過如下方式獲取插件項目中的圖片資源:

public static ImageDescriptor getImageDescriptor(String path) {
	return p_w_picpathDescriptorFromPlugin(PLUGIN_ID, path);
}

        或

Image p_w_picpath = Activator.getImageDescriptor("icons/workset.gif").createImage();

        這是因爲插件項目已經默認將icons配置進入了Classpath中,在"MANIFEST.MF"文件編輯器的"build.properties"頁中可以發現,如圖:

wKiom1RHzwLSFK9sAAOOwlu0gLo066.jpg

       按照本文中的解決方案操作之後,可以發現,resources文件夾也被添加到了bin.includes中了,如圖:

wKiom1RHzxuSTmNCAAOp7wJ1sig226.jpg

全文完。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章