当两个相同的jar包含在类路径中时,JVM如何工作

时间:2012-03-18 09:31:53

标签: java

这是我的同事的一个错误:有一个名为test.jar的jar,他修复了它的错误。然后他重新编译代码并构建了一个名为testnew.jar的新jar 问题是他将这两个jar放在classpath中的一个文件夹中。 因此,当程序运行时,行为是一种混乱。我不知道发生了什么事,但在删除test.jar之后,再一次没事了。

所以我想知道JVM的行为是什么。它是否在它遇到的第一个jar中使用类文件?或者是其他东西?

感谢。

4 个答案:

答案 0 :(得分:6)

据我所知,它没有定义。

Java有一个可插拔的类加载器系统,因此知道将会发生什么的唯一方法是查看ClassLoader class的文档,可能特别是ClassLoader#findClass method,它没有定义为此行为,并查看JLSJVM specs的相关部分,在这方面似乎都没有规定类加载器的约束。因此,除非您的Web容器使用的类加载器记录了该行为,否则您无法确定将加载哪个类。

赔率是,发现第一个匹配类的二进制名称的是加载的,但我们认为是行为之间存在差异案例以及指定和/或记录的行为。

答案 1 :(得分:5)

是的,默认情况下它使用第一个jar的类。这就是为什么你必须检查库目录中的重复项。对我和我的同事们来说,这么多次。

答案 2 :(得分:2)

如果有重复项,则会读取类路径中首先出现的那个。

修改 类路径文件通常看起来像这样..

<classpath>
        <classpathentry kind="lib" path="C:/Temp/test.jar"/>
        <classpathentry kind="lib" path="C:/Temp/testnew.jar"/>
    <classpathentry kind="output" path="build/classes"/>
</classpath>

如果您的类路径看起来像上面那样,那么您的JVM将首先查看test.jar,因为它首先出现在类路径中。如果您想自己测试它,请尝试在test.jar的条目上方移动testnew.jar的classpattry。您将看到它现在引用testnew.jar而不是test.jar。

参考:FindingClasses

答案 3 :(得分:1)

JVM加载类路径上的任何特定JAR。从java 6开始,也有一个通配符表示法。以下是几个例子。

java -cp ".:lib/example.jar" Main

上面只会加载当前目录和example.jar中的类。而下一个示例将使用任何jar来加载来自。

的类
java -cp ".:lib/*" Main

我不认为首先检查目录中的jar查找类的顺序,只是在列出文件时命令操作系统给出的顺序。

您的IDE(或者您用于运行程序的任何内容)可能正在使用后一种表示法运行程序。您可以更改它以便使用前者,但如果您更改jar的名称或添加新的名称,它将会中断。