在進行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)項目開發中的資源文件夾如圖:
插件Classpath配置如圖:
以"Run as -- Eclipse Application"方式測試插件時可以正常訪問,但打包發佈後,運行時得到的資源URL如圖:
2)解決方法:打開MANIFEST.MF的編輯器,在"Runtime"編輯頁,將資源文件夾(本文中爲"resources")配置進入Classpath,如圖:
結果爲:
添加後,可以發現"resources"文件夾的圖標發生改變,如圖:
打包發佈後,運行時得到的資源URL如圖:
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"頁中可以發現,如圖:
按照本文中的解決方案操作之後,可以發現,resources文件夾也被添加到了bin.includes中了,如圖:
全文完。