【问题标题】:Jar files spontaneously unable to locate internal root resourcesJar 文件自发找不到内部根资源
【发布时间】:2012-08-11 00:38:41
【问题描述】:

我正在开发一个使用工作 JVM 来做各种事情的应用服务器。

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

我有一个非常有趣的问题,其中 jar 文件 CLASSES 正确加载和执行代码,但是任何时候他们尝试访问 jar 文件中的资源(特别是使用 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");

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

【问题讨论】:

  • 唯一想到的是:JAR 可能使用自定义类加载器,这些加载器依赖于 JRE 实现中的一些奇怪行为(编写类加载器并非易事)。问题通常仅限于来自一个供应商的库吗?如果做Jarclass.getClassLoader().toString(),是否说明这不是JRE创建的ClassLoader?
  • 非常有见地的评论预测了我在原始帖子中甚至没有提到的事情。您绝对正确,其中一个供应商正在使用自定义类加载器,并且它覆盖了 JRE 标准类加载器,特别是用于加载资源。我的库都没有改变,但我没想到检查其他包含更改的类加载器的库。我调查了一下,发现这就是问题所在——供应商在他们对自定义类加载器所做的更改中犯了一个错误。谢谢!

标签: java class resources jar jvm


【解决方案1】:

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2012-02-04
      • 1970-01-01
      • 1970-01-01
      • 2016-06-18
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      • 2014-08-21
      • 1970-01-01
      相关资源
      最近更新 更多