如何在执行java.io.File或FileInputStream时引用OSGi包中的包含文件

我正在使用aQute Bnd工具集来创建一个OSGi包,并打包了一些相关的“资源”文件。 这包括我创建的资源目录中的* .css文件和* .xsd文件。

我在bundle.bnd文件中包含以下内容:

Include-Resource: resources/=resources/ 

当我进行构建时,生成的* .jar文件在jar包文件的顶级目录的resources目录中包含* .css和* .xsd文件。

但是,在实际代码中,我很难尝试将其作为类路径的一部分引用:

我尝试过以下方法:

 new File("resources/example.css"); 

我也尝试过:

 URL cssFile = this.getClass().getResource("resources/example.css"); try { file = new File(cssFile.toURI())); } catch(Exception e) { e.printStackTrace(); } 

我得到一个NullPointException错误或无法找到文件IOException错误(取决于我使用的是哪一个)。 我在调试配置模式下运行Eclipse Equinox以及Apache Felix(我们用于部署)时遇到此错误。 注意我试图在BundleActivator之外的Java类中执行此操作。

我是否需要始终参考BundleActivator的上下文,例如?

  /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ @Override public void start(BundleContext context) throws Exception { /* Service to host the Bundle interface. */ ServletContainerService service = new ServletContainerService(); service.addServlet(new ServletContainer(new AxisServlet(), true)); this.serverReg = context.registerService(ServletContainerService.class.getName(), service, null); cssFile = new File(context.getClass.getResource("resource/example.css")); } 

我认为上面的内容会起作用,但意味着我必须传递cssFile引用,而这些引用似乎并不优雅。

有没有办法在bundle / .jar文件的任何给定Java类中引用bundle jar文件中包含的’resources’目录的路径? 如果它涉及BundleContext,有没有办法在任何Java类中引用它?

任何帮助都感激不尽。


我已经看过并包含OSGi包的其他资源,但看起来你需要BundleContext。

我可能已经找到了一个可能的解决方案: http : //www.vogella.de/blog/tag/plugin/

看起来Vogella有一些示例代码:

 URL url; try { url = new URL("platform:/plugin/de.vogella.rcp.plugin.filereader/files/test.txt"); InputStream inputStream = url.openConnection().getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(inputStream)); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); } in.close(); } catch (IOException e) { e.printStackTrace(); } 

有没有人知道如果它不是一个插件,如果我使用不同的OSGi环境,这条路径是否相同,例如。 Equinox Eclipse与Apache Felix? 例如url = new URL("platform:/plugin/de.vogella.rcp.plugin.filereader/files/test.txt");

Bundle接口有一个getEntry(java.lang.String path)方法,它返回一个Url并记录为:

返回此捆绑包中指定路径的条目的URL。 此捆绑包的类加载器不用于搜索条目。 仅搜索此包的内容以查找该条目。 指定的路径始终相对于此捆绑包的根目录,可以以“/”开头。 路径值“/”表示此捆绑包的根。

我认为答案应该简单如下:

 URL cssFile = this.getClass().getResource("/resources/example.css"); 

即确保路径中有一条前沿斜线。 你没有一个前导斜杠,这会使它与你正在调用的类“相对”。

或者,以下应该起作用:

 this.getClass().getClassLoader().getResource("resources/example.css"); 

如果您使用Eclipse / Equinox构建,那么您可以通过调用类似于以下内容的BundleActivator中的BundleContext来获取Bundle的位置:

 Bundle yourBundle = Platform.getBundle("bundleSymbolicName"); Path relativePathToBundle = new Path("/relativePath"); FileLocator.openStream(yourBundle, relativePathToBundle, false); 

Platform和FileLocator类来自org.eclipse.core.runtime插件,因此如果您依赖于该插件,那么上面的内容应该允许您访问您的资源。