从 .war 文件加载类的顺序

2022-09-03 12:36:18

在以下场景中,我有一个关于保证的问题(如果有的话)(请注意,问题不是“如何以不同的方式执行此操作?”,问题实际上是关于以下情况下的类加载顺序(以更好地了解类加载的工作原理)。

这是假设的场景...有一个 .war 文件具有以下(部分)目录结构:

 WEB-INF/classes/com/acme/Bunny.class
 .
 .
 .
 WEB-INF/lib/acme.jar

Bunny.class文件都导入了 acme 中的其他类.jar

Web-INF/classes/... 中的 Bunny.class 是唯一一个与 acme .jar类具有相同名称/路径的类。

.jar文件acme.jar还包含com.acme.Bunny(并且没有使用特殊的类加载器技巧)。

我理解Java规范保证在程序实际使用(或故意“手动类加载”)之前不会加载类,这就是为什么如果你填充数千个.jar,比如说,在.war中,类加载器不会开始类加载数以万计的类。

(编辑)

但是,上面示例中的两个类的加载顺序如何呢?

应该这样说:

但是,如何确定加载上述两个类中的哪一个呢?

或类似的东西:)

有一个保证:com.acme.Bunny应该在com.acme的任何其他类之前使用。

基本上,在维基百科上,写了以下内容:

最复杂的 JAR 地狱问题出现在利用类加载系统的全部复杂性的情况下。Java 程序不需要只使用一个“扁平”类装入器,而是可以由几个(或者实际上无限数量的)嵌套的、协作的类装入器组成。由不同的类加载器加载的类可能会以开发人员无法完全理解的复杂方式进行交互,从而导致无法解释的错误或错误。

所以我想知道:我能确定/classes/com/acme/Bunny.class会在web-INF/lib/dir中的.jar之前加载吗?


答案 1

所选答案错误。Servlet 规范版本 2.4 和 3.0 明确指出,首先加载 WEB-INF/类,然后加载 WEB-INF/lib

Servlet 2.4:http://download.oracle.com/otn-pub/jcp/servlet-2.4-fr-spec-oth-JSpec/servlet-2_4-fr-spec.pdf - SRV.9.5 节,最后一段

Servlet 3.0:http://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-oth-JSpec/servlet-3_0-final-spec.pdf - 第 10.5 节,最后一段

Web 应用程序类装入器必须首先从 WEB-INF/classes 目录装入类,然后从 WEB-INF/lib 目录中的库 JAR 装入类。


答案 2

此答案不正确,但无法删除,因为它是可接受的答案。请参阅下面的@Sajeev的答案。


推荐