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

Dam*_*ien 37 java tomcat classloader

任何人都可以解释从Tomcat中的lib目录加载jar文件的顺序吗?是字母的吗?随机?还是其他一些订单?

Bal*_*usC 37

这些都是在Tomcat的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)

如果您想保证 JAR Y之后加载JAR X,那么您需要将JAR X放在上面列表中稍后出现的其中一个位置.

但是有一些例外,它们在tomcat文档中提到过

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

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

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

  • 它是否解释了*单个目录*中的文件的加载顺序? (2认同)

小智 33

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

更具体地说,如果你看一下Tomcat 6的源代码FileDirContext,那么该方法会list()调用Arrays.sort()找到的jar文件名数组.

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

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

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

  • 我可以为Tomcat 5 + 6确认这个,但是目前有问题,因为Tomcat 8.0.9的行为不是那样的! (7认同)
  • +1用于指出已发布文档的"问题" (5认同)

use*_*008 24

在WEb-INF/lib文件夹中订购加载的jar.

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

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

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