如果在两个jar文件中打包相同的类,将调用哪个java类文件?

时间:2012-03-18 10:40:28

标签: java

我正在开发开源项目。截至目前,我在任何课程中都没有任何自定义。所以使用opensource项目提供的所有jar文件。我的问题是,如果我修改一个java文件,编译它并打包它具有相同文件夹结构的新jar文件,在服务器启动或运行时是否会出现任何问题?如果不是将调用哪个类文件(默认文件或我的自定义java类文件)?

2 个答案:

答案 0 :(得分:14)

实际上它取决于很多因素:

  • 如果两个jar文件都在同一个ClassLoader中,例如Java类路径(-cp选项),通常它应该是jar列表顺序中找到的第一个文件。

  • 如果部署在JavaEE容器中,例如在EAR文件或WEB-INF/lib或WAR文件中,则无法保证容器将在两个初创公司之间加载相同的类。在这种情况下,唯一确定的是在WEB-INF/classes之前搜索WEB-INF/lib

  • 在复杂的ClassLoader层次结构中,默认行为是父优先搜索,但是由于部署描述符(WebLogic),JavaEE实现引入了父上次策略(WebSphere)或过滤等机制

由于META-INF/MANIFEST.MF属性,选项可能是在Class-Path文件中声明jar file dependencies。它应该在ClassLoader级别强制执行加载顺序,尤其是在使用java -jar myapp.jar启动时,但它可能依赖于JavaEE上下文中的实现。

备注:在使用OpenSource项目时,提交变更请求并发布您的更改或改进以便社区从中受益可能是公平的。然后,您的项目可能会更新到主流,而不会在ClassPath中出现野生补丁的困难。

答案 1 :(得分:5)

类加载器正在寻找所需资源所在的第一个位置。这意味着如果具有相同名称和包的类出现在2个罐中,则将使用第一个找到的类。哪一个是第一个?根据类路径:例如,如果类A出现在jar的one.jar和two.jar中,并且您的命令行是:

java -cp one.jar;two.jar MyMain`

将使用one.jar中的版本。但是如果命令行是

java -cp two.jar;one.jar MyMain`

来自two.jar的类将被实例化。