我有一个嵌入在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中加载资源吗?
答案 0 :(得分:5)
我假设SomeClass
位于嵌入式jar中(例如,somejar.jar
),而someResource.xml
位于外部jar中,位于lib
目录中。
在这种情况下,无法在非OSGi上下文中找到它。让我们孤立地看一下这两种情况。
使用常规(非OSGi特定)资源加载机制,提供可以从someResource.xml
访问Bundle-ClassPath
,可以很好地访问Bundle-ClassPath: ., somejar.jar
。例如,如果您有以下清单标题,
"lib/someResource.xml"
您将能够使用somejar.jar
访问您的资源。
注意类路径上的点:这意味着您可以从jar的根目录获取类和资源。如果您忘记了这一点,您将只能访问SomeClass
内的课程和资源。
如果您没有使用OSGi,那么就没有(相当简单的)方法可以获得我所知道的内部jar中的类和资源。
根据您希望捆绑包的外观,您现在有两种选择。
somejar.jar
是否真的有必要嵌入jar中?如果是这样,你就会感到茫然,而你的jar只能使用OSGi。就个人而言,我会选择选项2:除非您在合并'罐子时拥有可能会互相覆盖的资源,否则在您的捆绑包中存在轻微的资源是没有问题的。
答案 1 :(得分:2)
我的假设是:
如果有问题的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中的工作方式。