2012-03-18 70 views
6

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

+0

我相信JVM会使用它可以在类路径中找到的第一个jar文件中的类。而类似的问题已经回答了今天本身 “JVM是如何工作的,当两个相同的jar包含在类路径”的[JVM是如何工作的,当两个相同的jar包含在类路径( – sachinrahulsourav 2012-03-18 10:45:50

+0

可能重复http://stackoverflow.com/问题/ 9757279/how-jvm-works-when-two-same-jar-include-in-classpath) – 2012-03-18 10:50:26

回答

10

事实上,这取决于很多因素:

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

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

  • 搜索在复杂的类加载器的层次结构,默认的行为是家长第一次搜索,但JavaEE的实现已经推出了像父母最后一个策略(的WebSphere)或过滤机制由于部署描述符(的WebLogic)

的选择可能是jar file dependenciesMETA-INF/MANIFEST.MF文件由于申报的Class-Path属性。它应该在ClassLoader级别强制执行加载顺序,特别是在使用java -jar myapp.jar启动时,但它可能取决于JavaEE上下文中的实现。

备注:当使用OpenSource项目时,提交更改请求并发布更改或改进以便社区从中受益可能是公平的。然后,您的项目可能会更新为主流,而ClassPath中没有这种通配符的困难。

+0

如您所说如果两个jar文件都在同一个ClassLoader中,例如Java classpath(-cp选项),通常它应该是第一个以jar列表顺序找到的文件。但是,第二点,你说过,如果在tomcat中部署在webcontainer中的war文件是这种情况,那么将不会保证哪个类文件被调用。那是对的吗? – 2012-03-18 11:48:47

+0

还有一点。你说一个选项可能是由于Class-Path属性在META-INF/MANIFEST.MF文件中声明jar文件依赖关系。它应该在ClassLoader级别执行加载顺序,但它可能取决于JavaEE上下文中的实现。只是为了确认我的理解,如果A类包装在两个jar文件J1和J2中。 A类从B类调用(J3包装)。现在如果我们想从JJ中调用A类,那么我们需要在jar J3的清单文件中提到这一点。正确? – 2012-03-18 12:07:38

+0

是的。 J3清单必须包含Class-Path:j2.jar,J2清单必须包含Class-Path:j1.jar。所以它首先执行加载顺序:j3,然后是j2,然后是j1。当使用Main-Class属性打包时特别有用。 – 2012-03-19 07:53:06

1

类加载器寻找在需要资源位于首位。这意味着如果具有相同名称和包装的班级出现在2个瓶子中,则会使用第一个找到的班级。第一个是哪一个?根据类路径:举例来说,如果A类出现在罐子one.jar和two.jar和您的命令行是:

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

从one.jar版本将被使用。但是,如果命令行是

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

从two.jar类将被实例化。

+4

你有参考文献说这是*指定/记录*行为吗?我[没有看到一个](http://stackoverflow.com/questions/9757279/how-jvm-works-when-two-same-jar-be-included-in-classpath/9757720#9757720)。 – 2012-03-18 10:58:17

+0

当它是'java -cp/src/lib/* MyMain'和lib目录包含one.jar和two.jar时会发生什么? – enator 2017-11-03 12:23:08

相关问题