2010-09-28 54 views
11

当我使用aQute BND工具集来创建一个OSGi包,并打包了一些相关的“资源”文件引用的包含文件中的OSGi bundle。这包括我创建的资源目录中的* .css文件和* .xsd文件。如何执行java.io.File的或的FileInputStream

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

Include-Resource: resources/=resources/ 

当我做一个生成,生成的* .jar文件已在中* .css和* xsd文件资源目录在jar包文件的顶层目录中。

但是,我在试图把这种现象称为类路径中的部分有困难的实际代码:

我曾尝试以下:

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引用周围似乎并不优雅。

有什么办法来指代包含在任何给定的Java类捆绑JAR文件是包/ .jar文件的一部分,“资源”目录的路径?如果涉及到BundleContext,有没有办法在任何Java类中引用它?

任何帮助将不胜感激。


我看过了并且Including additional resources with OSGi bundles但看起来你需要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");

回答

9

Bundle interface具有getEntry(java.lang.String path)方法,该方法返回一个地址和被记录为:

返回的URL在指定的路径在该束中的条目。该包的类加载器不用于搜索条目。只有这个包的内容被搜索到条目。 指定的路径始终相对于此捆绑包的根目录,并可能以“/”开头。路径值“/”表示该捆绑的根。

+0

反正是有访问它的BundleActivator的上下文之外?我猜你是指做这样的事情:public void start(BundleContext context){Bundle bundle = context.getBundle(); InputStream in = bundle.getEntry(“/ resource/example.css”)。openStream(); }。但是,我正在寻找一个解决方案(如果有的话)在BundleActivator之外访问它。我看了一下http://www.eclipsezone.com/eclipse/forums/t101557.html,但我仍然感到困惑 – herbyme 2010-09-28 08:13:39

+0

你有没有想过从bundle id中获取一个Bundle对象? – 2010-09-28 09:01:00

+0

我可以获取条目,但问题是getEntry()仅提供相对路径,而不提供包的完整(根)路径:http://www.techinfopad.com/spring/101600333-getting-root -path-的-A-bundle.html。 – herbyme 2010-09-29 06:23:33

2

如果您正在使用的Eclipse/Equinox的建设,那么你可以通过调用像从outwith所含的BundleActivator中的BundleContext得到一个包的位置:

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

平台和FileLocator类来自org.eclipse.core.runtime插件,所以如果你有依赖关系,那么上面应该允许你访问你的资源。

+0

我试图避免使用org.eclipse.core.runtime插件,因为我们的部署决定使用Apache Felix(除非有合并的方法)。如果我在Eclipse运行时环境下运行它,以上工作。 – herbyme 2010-09-29 03:32:10

3

我想答案应该是作为下面简单:

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

即确保路径中有一个前导斜杠。你没有使用前导斜杠,这会使它与你所呼叫的课程“相对”。

或者下面应该工作:

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

我选择了此解决方案,但在尝试导入所有目录的值时遇到了问题,例如我正在使用BluePrint CSS,并且在使用this.getClass()。getClassLoader()。getResource(“resources/css”)时遇到了问题,因为不仅有许多文件,而且还有子目录。我最终将文件“复制”到临时位置,但这会导致一些性能问题。 – herbyme 2010-10-05 00:35:26