Jar文件自发地无法找到内部根资源

时间:2012-08-14 16:49:28

标签: java class resources jar jvm

我正在使用一个使用工作者JVM来执行各种操作的应用程序服务器。

使用-cp开关启动worker jvms,并指定包含供应商库和其他重要功能的JAR文件。

我有一个非常有趣的问题,其中jar文件CLASSES正确加载并执行代码,但是当他们尝试访问jar文件中的RESOURCE时(特别是使用getResourceAsStream()方法)然后它会爆炸声称它无法找到它。我已经验证了这些资源肯定存在于正在加载的JAR中,实际上如果我操纵JAR以在外部定位资源,它就可以工作。问题是这些都是专有的库,并没有附带来源,所以我瘫痪了,因为我必须通过反编译和方法输入断点来做所有事情。

也许最奇怪的部分是这些库已经存在了很多个月,并且一直在其他(包括生产)应用服务器上工作。

他们在JRE 1.6.0_17

所以我的问题是

  • 为什么带有-cp条目的JVM能够从jar而不是RESOURCES
  • 加载CLASSES
  • 这个领域的任何内容都会从JRE 1.6.0_06变为1.6.0_17(最近发生了变化)

为了澄清,在JAR结构中,这些资源位于jar的根部,即:

resource.prop
META-INF/Manifest
package/package/class.class

JAR本身在加载时显然在类路径上。 但是以下所有解决方案都是NULL(是的,这让我疯了,所以我确实尝试了所有3):

Jarclass.getClassLoader().getResourceAsStream("./resource.prop");
Jarclass.getClassLoader().getResourceAsStream("/resource.prop");
Jarclass.getClassLoader().getResourceAsStream("resource.prop");

这与Can't access resource in a JAR on all computers类似,但没有解决该问题。

2 个答案:

答案 0 :(得分:0)

您是否检查过JAR中的manifest.mf文件?这是控制用于加载位于JAR内的资源的类路径的最简单方法之一(如果不是唯一的方法)。

从JAR读取资源仅与用于加载JAR的类路径部分相关。对于类文件,JAR中的文件夹结构足以让类加载器加载类,基本上是[CLASSPATH] / [Package] / [Classname]。

对于资源而言,这是另一回事。 JAR的根被添加到CLASSPATH但不添加到任何子目录,因此如果“resource.prop”位于jar的根目录中,则您提供的三个示例中的任何一个都可以使用。既然你说他们已经在罐子的根部,它只会加深神秘感。

JAR是否以某种方式发生了变化,就像旧版本工作而新版本没有?

最近是否更改了应用服务器的CLASSPATH设置?我们遇到了IBM WebSphere Application Server的一个问题,我们不得不将类加载器的规则设置为'parent last'(至少如果我的内存没有让我失败),那么它将首先使用JVM实例中的Classpath,然后使用classloader for WebSphere,因为我们加载的log4j.jar比IBM启动的版本早,包括在较新版本的WebSphere中。

另一种选择是扩展JAR,更新manifest.mf文件以包含对属性的绝对引用,然后将文件重新打包成自定义版本。

答案 1 :(得分:0)

检查放置非工作罐的目录名称。当我的应用程序被复制到dir时,我的名称中包含符号!%,我遇到了类似的问题。