Java:JVM 占用类路径上的多个资源中的哪一个?
如果我在类路径上有多个同名文件(例如,我有多个 .jar
和 log4j.properties
),那么 JVM 选择一个文件时遵循什么规则?
If I have multiple files of the same name on classpath (e.g. I have multiple .jar
with log4j.properties
), what are the rules JVM follows to chose one?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它是通过使用
-classpath
选项指定资源(即通常是jar 文件)的顺序来指定的。类路径上“较早”的资源优先于在其之后指定的资源。这也可以在应用程序的清单文件中设置,然后您不需要提供-classpath
选项。您可能需要查看这些文章了解如何使用清单文件。关于“如何找到类”的详尽描述可以在此处找到,其中JAR-class-path Classes 部分描述了 JAR 文件搜索的逻辑。
It is specified by the order in which the resources (i.e. usually jar files) are specified using
-classpath
option. Resources 'earlier' on the classpath take precedence over resources that are specified after them. This can be also set in the manifest file of your application and then you don't need to provide-classpath
option. You may want to check these articles on how to work with manifest files.The exhaustive description of "how classes are found" can be found here, where the section on JAR-class-path Classes describes the logic of JAR-files searching.
ClassLoader 确定资源的位置(取自 ClassLoader JavaDoc):
因此,无论在代码中调用 Class#getResource 或 Class#getResourceAsStream,都会发生这种情况(取自 Class.java)
ClassLoader.java:
其中 ClassLoader#findResource 实际上会被 ClassLoader 实现覆盖。这意味着应用程序服务器、TomCat 上的行为是不同的,或者如果您从 jar 文件运行,则它取决于您当前所处环境的 ClassLoader 实现。
这里是一个示例,您可以使用它来跟踪特定情况下的幕后情况。
The ClassLoader determines where a resource will be located (taken from ClassLoader JavaDoc):
So wherever in your code Class#getResource or Class#getResourceAsStream is called, this happens (taken from Class.java)
ClassLoader.java:
where ClassLoader#findResource is actually to be overwritten by the ClassLoader implementation. This implies that the behavior is different on an application server, a TomCat or if you are running from a jar file, it depends on the ClassLoader implementations of the environment you are currently in.
Here is an example that you may use to trace what's going under the hood in your particular case.
我正在提供一个经过验证的案例,如果类路径是一个文件夹中的所有 jar,并且您想要优先考虑其中一个(或某些),则这是行不通的:
Windows:
Linux:
看来第一个路径 bin/prioritized .jar 被忽略只是因为第二个带有通配符的将其包含在自己的范围内。这有效地破坏了类路径的指定顺序。
因此,为了让多个资源具有优先级(在 Java 10.0.1 上测试),您需要将它们放在不重叠的作用域中,然后它们才能工作。
I am contributing a proven case that if classpath is, say, all jars in a folder, and you want to prioritize one (or some) of them, this does not work:
Windows:
Linux:
It appears that the first path bin/prioritized.jar is ignored just because the second one with a wildcard includes it in its own scope. This is what effectivelly breaks the specified order of classpaths.
Therefore, in order to have multiple resources prioritized (tested on Java 10.0.1), you need to put them in non-overlapping scopes and then they will work.