从lib目录加载jar文件的顺序

时间:2011-03-29 15:09:33

标签: java tomcat classloader

有人能解释一下从Tomcat中的lib目录加载jar文件的顺序吗? 它按字母顺序排列吗?随机?还是其他一些订单?

5 个答案:

答案 0 :(得分:36)

所有这些都在Tomcat's ClassLoading HOW-TO中描述。它不一定按字母顺序排列。如果您发现了这种行为,那么如果您打算让Web应用程序在服务器之间移植,那么它应该绝对不是。例如,Tomcat 6“巧合地”命令它,但Tomcat 8没有。

总结,加载顺序如下:

  1. bootstrap / system(JRE/lib,然后是server.loader
  2. webapp库(WEB-INF/classes,然后是WEB-INF/lib
  3. 公共图书馆(common.loader,然后是Tomcat/lib
  4. webapp-shared libraries(shared.loader
  5. 如果您想保证在 JAR Y之后加载JAR X,那么您需要将JAR X放在以后出现的中的一个中上面的列表。

    但是有一些例外,tomcat docs

    中提到了这些例外情况
      

    最后,Web应用程序类加载器将始终首先委托JavaEE API类来执行Tomcat(Servlet,JSP,EL,WebSocket)实现的规范。 Tomcat中的所有其他类加载器都遵循通常的委托模式。

    这意味着如果webapp包含任何JavaEE类(javax.*),那么tomcat将忽略它。

    对于每个加载器,只要需要导入/执行并且尚未加载,JVM就会按顺序加载这些类。

答案 1 :(得分:32)

实际上,按字母顺序排列! (在特定目录中,例如原始海报提到的'lib'目录。)

更具体地说,如果您查看Tomcat 6的源代码,在类FileDirContext中,方法list()会在找到的jar文件名数组上调用Arrays.sort()。 / p>

我也手动测试了这个。我用一个调用HelloWorld.getGreeting()的JSP创建一个war,并将两个几乎相同的包含HelloWorld略有不同版本的jar放入WEB-INF / lib目录中。一个说“你好,世界”,另一个说“再见,残酷的世界”。

如果我将“Hello,world”版本命名为a.jar,并将“goodbye”版本命名为b.jar,并重新启动Tomcat,则会收到“Hello”文本。如果我用另一个方式命名罐子并重新启动Tomcat,我会得到“Goodbye”文本。

据我所知,此行为未记录,未指定,不应依赖。但它现在是按字母顺序排列的。

答案 2 :(得分:23)

在WEb-INF / lib文件夹中订购加载的罐子。

对于tomcat 5-7,顺序是按字母顺序排列的。它使用sort。

对于tomcat 8,由底层文件系统随机决定。

https://issues.apache.org/bugzilla/show_bug.cgi?id=57129

答案 3 :(得分:1)

我完全同意BalusC提供的答案。只指向添加是指从相应的类加载器加载JAR时它确实按字母顺序检查。

我有一种情况要加载" XSSFWorkbook"在我的网络应用程序中从excel表读取数据,并有两个JARS" poi-ooxml-3.9.jar"和" org.eclipse.birt.runtime_4.3.1.v20130918-1142.jar"具有相同的类名和包结构。我简单地将后者重新保留,所以按字母顺序排在前一个旁边,它对我来说是一个技巧。只想分享一样。

祝你好运

答案 4 :(得分:0)

在我们的WebSphere env中,不同的机器以不同的顺序加载jar。所以我同意user2193008。我们在生产环境中遇到类加载器问题,在较低环境中相同的代码可以正常工作。我们通过删除lib中的重复jar来解决问题,例如,有两个版本的spring jar,即spring_v1.jar和spring_v2.jar,如果classloader首先加载v1,代码可以正常工作,但是如果classloader首先加载v2,则麻烦。