这是我的同事的一个错误:有一个名为test.jar的jar,他修复了它的错误。然后他重新编译代码并构建了一个名为testnew.jar的新jar 问题是他将这两个jar放在classpath中的一个文件夹中。 因此,当程序运行时,行为是一种混乱。我不知道发生了什么事,但在删除test.jar之后,再一次没事了。
所以我想知道JVM的行为是什么。它是否在它遇到的第一个jar中使用类文件?或者是其他东西?
感谢。
答案 0 :(得分:6)
据我所知,它没有定义。
Java有一个可插拔的类加载器系统,因此知道将会发生什么的唯一方法是查看ClassLoader
class的文档,可能特别是ClassLoader#findClass
method,它没有定义为此行为,并查看JLS和JVM 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。
答案 3 :(得分:1)
JVM加载类路径上的任何特定JAR。从java 6开始,也有一个通配符表示法。以下是几个例子。
java -cp ".:lib/example.jar" Main
上面只会加载当前目录和example.jar中的类。而下一个示例将使用任何jar来加载来自。
的类java -cp ".:lib/*" Main
我不认为首先检查目录中的jar查找类的顺序,只是在列出文件时命令操作系统给出的顺序。
您的IDE(或者您用于运行程序的任何内容)可能正在使用后一种表示法运行程序。您可以更改它以便使用前者,但如果您更改jar的名称或添加新的名称,它将会中断。