在进行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)项目开发中的资源文件夹如图:
![](https://i-blog.csdnimg.cn/blog_migrate/c2615ef0649daa5e890785d086f6ca0c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/807c2bfad9268c6c7f5f1e5e41d03303.png)
以"Run as -- Eclipse Application"方式测试插件时可以正常访问,但打包发布后,运行时得到的资源URL如图:
![](https://i-blog.csdnimg.cn/blog_migrate/2367eee729214136457876b4061b1126.png)
2)解决方法:打开MANIFEST.MF的编辑器,在"Runtime"编辑页,将资源文件夹(本文中为"resources")配置进入Classpath,如图:
![](https://i-blog.csdnimg.cn/blog_migrate/0bb89bbe6466641eb17c02714a677762.png)
结果为:
![](https://i-blog.csdnimg.cn/blog_migrate/65d7dada74f4374351f10d1cedfb8d26.png)
添加后,可以发现"resources"文件夹的图标发生改变,如图:
![](https://i-blog.csdnimg.cn/blog_migrate/a54e1b4ed5a58bac14c61b36239fb4bf.png)
打包发布后,运行时得到的资源URL如图:
![](https://i-blog.csdnimg.cn/blog_migrate/fb0619717ccb0815f571e4773cfd4a4d.png)
3)结论:
必须将资源路径配置到Bundle的类加载路径中,才能保证Bundle能够定位、访问这些资源。其实可以通过插件加载icons目录下的图片文件的机制,联想到其他资源文件的加载。在Eclipse API中可以通过如下方式获取插件项目中的图片资源:
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
或
Image image = Activator.getImageDescriptor("icons/workset.gif").createImage();
这是因为插件项目已经默认将icons配置进入了Classpath中,在"MANIFEST.MF"文件编辑器的"build.properties"页中可以发现,如图:
按照本文中的解决方案操作之后,可以发现,resources文件夹也被添加到了bin.includes中了,如图:
全文完。