Java 加载非 JAR 扩展名的文件

Java loads file with non JAR extension

这是我的 Java 版本:

# java -version
java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 2.2)
IBM J9SE VM (build 2.2, J2RE 1.4.2 IBM J9 2.2 Linux amd64-64 j9xa64142-20080130 (JIT enabled)
J9VM - 20071205_1933_LHdSMr
JIT  - r7_level20071016_1845)

(这是 IBM Information Server 的一部分)

我必须将一些更新部署到实时应用程序,因此我必须替换现有的 jar 文件之一。显然,我备份了旧的 mylibrary.jar 文件并将其命名为 mylibrary.jar.old.

启动应用程序后,经过数小时痛苦的调试后,我注意到 - 由于某种原因 - mylibrary.jar 未加载,而 mylibrary.jar.old 实际上已加载。

确实,它们都位于 class 路径中,但我希望不会加载具有非 JAR 扩展名的文件。我确定这是怎么回事,我可以重现这个问题。

我错过了什么吗?我无法在 Oracle 的网站上找到与此相关的任何信息。


编辑: 我也用来自 Oracle 的 Java 进行了测试,同样的事情发生了。

java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

实际上加载的是 classes,而不是 jar。 jar 是一种 zip 格式,JVM 通过解压缩 jar 延迟加载 classes。

使用 java extension 机制,JVM 可能会在不一定具有 .jar 扩展名的文件 ( zip ) 中加载 classes。

页面 here 详细解释了 VM 如何加载甚至没有扩展名的 jar。

你的mylibrary.jar.old格式的旧jar可以完美解压。使用 7-zip 进行测试。所以 JVM 可以在需要时从这个旧 jar 加载 classes,现在为什么它不从 mylibrary.jar 而不是 mylibrary.jar.old 中获取?我猜这是因为 JVM 默认 class 加载可能会通过 Date Modified 查看 jar 并且因为已经找到 class JVM 不会在其他 jars 中查找。

此外,我宁愿从您的应用程序中删除 mylibrary.jar.old 并将其备份到 java classpath.

中未指定的目录中的其他位置