如何在另一个jar中获取资源

时间:2010-12-22 00:37:00

标签: java osgi classloader

我有一个嵌入在bundle中的jar,需要获取与它一起打包的资源,如下所示:

MyBundle
  -\ src
  -\lib
    -\MyEmbeddedJar
      -\src
        -\SomeClass
      -\someResource.xml

我试图从'SomeClass'访问'someResource.xml',如下所示:

SomeClass.class.getResource( "someResource.xml" ); 

但我没有运气。我已经尝试了附加CWD的几个变体(例如:'。/ someResource.xml'),但我无法加载此资源。

我知道“正确”的方法是使用Activator来获取正确的类加载器,但嵌入式jar可以在其他项目中使用,所以我不想只需要添加OSGi特定代码让它与OSGi玩得很好。

还有其他方法可以在OSGi的OSGi中加载资源吗?

4 个答案:

答案 0 :(得分:5)

我假设SomeClass位于嵌入式jar中(例如,somejar.jar),而someResource.xml位于外部jar中,位于lib目录中。

在这种情况下,无法在非OSGi上下文中找到它。让我们孤立地看一下这两种情况。

在OSGi中

使用常规(非OSGi特定)资源加载机制,提供可以从someResource.xml访问Bundle-ClassPath,可以很好地访问Bundle-ClassPath: ., somejar.jar 。例如,如果您有以下清单标题,

"lib/someResource.xml"

您将能够使用somejar.jar访问您的资源。 注意类路径上的点:这意味着您可以从jar的根目录获取类和资源。如果您忘记了这一点,您将只能访问SomeClass内的课程和资源。

不使用OSGi

如果您没有使用OSGi,那么就没有(相当简单的)方法可以获得我所知道的内部jar中的类和资源。

您的选择

根据您希望捆绑包的外观,您现在有两种选择。

  1. somejar.jar是否真的有必要嵌入jar中?如果是这样,你就会感到茫然,而你的jar只能使用OSGi。
  2. 如果您可以选择将{{1}}“解压缩”到您的jar中,则可以解决问题,并且您的jar可以在两种情况下都有效。
  3. 就个人而言,我会选择选项2:除非您在合并'罐子时拥有可能会互相覆盖的资源,否则在您的捆绑包中存在轻微的资源是没有问题的。

答案 1 :(得分:2)

我的假设是:

  1. 我不太确定我对问题的描述与图表的匹配程度如何。 * .jar文件在哪里?
  2. 正在尝试的捆绑包 访问嵌入式jar是一样的 包含嵌入的包 罐。
  3. 根据OSGi不可知论,我是 假设嵌入的jar是 没有明确地暴露为一部分 当前bundle的classpath和 它没有作为另一个加载 OSGi捆绑。
  4. 如果有问题的jar本身是当前类加载器的资源,那么首先需要将jar作为资源或InputStream,例如使用MyBundleClass.class.getResourceAsStream("/pathToJar.jar");,然后用{{1}包装它}}。然后,继续调用java.util.jar.JarInputStream,直到找到getNextJarEntry()的JarEntry对象。

答案 2 :(得分:0)

我将接受@ Angelo的解决方案,因为它给了我如何解决这个问题的想法,但是,我想添加更多信息 - 因此我的回答。

我的工作是向SomeClass添加另一个构造函数,该构造函数包含一个java.net.URL实例。我还将someResource.xml复制到了bundle的根目录中。

然后我像这样更新了包中SomeClass的实例化:

new SomeClass( FileLocator.find( Activator.getDefault().getBundle(), new Path( "./someResource.xml" ), new HashMap< String, String >() ) );

这对我来说似乎是一个非常大的黑客。如果我无法编辑SomeClass的内容怎么办?我想我必须解压缩它或者我不得不将它包装到它自己的包中?

答案 3 :(得分:0)

我将做出以下假设:

  

embedded.jar
  SRC / SomeClass.class
  someResource.xml

并且bundle包含embedded.jar,embedded.jar位于Bundle-Classpath。

在这种情况下,SomeClass.class.getResource("someResource.xml")将在名为src/someResource.xml的类路径中查找资源,因为SomeClass位于包src中。为了在jar的根目录中获取someResource.xml,您需要改为SomeClass.class.getResource("/someResource.xml")

这不是特定于OSGi的,这只是资源加载在Java中的工作方式。