0

我正在使用工作 JVM 来做各种事情的应用程序服务器。

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

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

也许最奇怪的部分是这些库已经好几个月没有改变了,并且一直在其他(包括生产)应用程序服务器中工作。

它们在 JRE 1.6.0_17 上

所以我的问题是

  • 为什么带有 -cp 条目的 JVM 能够从 jar 中加载 CLASSES 而不是 RESOURCES
  • 此领域中的任何内容是否从 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");

这看起来类似于无法在所有计算机上访问 JAR 中的资源,但该问题没有解决方案。

4

2 回答 2

0

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

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

对于资源来说,则是另外一回事。JAR 的根目录被添加到 CLASSPATH 但不是任何子目录,因此如果“resource.prop”位于 jar 的根目录中,那么您提供的三个示例中的任何一个都可以工作。既然你说它们已经在罐子里了,那只会加深谜团。

JAR 是否以某种方式发生了变化,例如旧版本有效而​​新版本无效?

您的应用服务器的 CLASSPATH 设置最近是否更改过?我们在 IBM 的 WebSphere Application Server 上遇到了一个问题,我们必须将类加载器的规则设置为“最后一个父级”(至少如果我的记忆在这里没有让我失望的话),以便它首先使用 JVM 实例中的类路径,然后然后使用 WebSphere 的类加载器,因为我们加载了一个比 IBM 开始包含在较新版本的 WebSphere 中的 log4j.jar 更旧的 log4j.jar。

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

于 2012-08-14T17:30:29.670 回答
0

检查放置非工作 jar 的目录的名称。当我的应用程序被复制到带有符号!或其%名称的目录时,我遇到了类似的问题。

于 2012-08-14T17:36:38.807 回答