Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of class loading from a .war file

I've got a question regarding the guarantees, if any, in the following scenario (note that the question is not "How to do this in a different way?", the question is really about class loading order in the following case (to better understand how class loading works).

Here's the hypothetical scenario... There's a .war file that has the following (partial) directory structure:

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

Both Bunny.class files have import referencing other classes from acme.jar

Bunny.class in WEB-INF/classes/... is the only class that has the same name/path that a class from acme.jar.

The .jar file acme.jar also contains com.acme.Bunny (and there are a no special class loader tricks used).

I understand that the Java spec guarantees that a class won't be loaded until it is actually used (or "manually class-loaded" on purpose) by the program, which is why if you stuff thousands of .jar, say, in a .war, the classloader(s) don't start classloading tens of thousands of classes.

(edit)

But what about the order in which the two classes in the examples above are loaded?

should have been phrased:

But how is it decided which one of the two classes above is loaded?

or something like that :)

There's one guarantee made: com.acme.Bunny shall be used before any other class from com.acme....

Basically, on Wikipedia, the following is written:

The most complex JAR hell problems arise in circumstances that take advantage of the full complexity of the classloading system. A Java program is not required to use only a single "flat" classloader, but instead may be composed of several (or, in fact, an indefinite number of) nested, cooperating classloaders. Classes loaded by different classloaders may interact in complex ways not fully comprehended by a developer, leading to inexplicable errors or bugs.

So I'm wondering: can I be sure that /classes/com/acme/Bunny.class will be classloaded before the one from .jar inside the WEB-INF/lib/ dir or not?

like image 233
SyntaxT3rr0r Avatar asked Dec 16 '10 23:12

SyntaxT3rr0r


People also ask

What is the order of class loading in Java?

Note: The ClassLoader Delegation Hierarchy Model always functions in the order Application ClassLoader->Extension ClassLoader->Bootstrap ClassLoader. The Bootstrap ClassLoader is always given the higher priority, next is Extension ClassLoader and then Application ClassLoader.

What is the structure of a WAR file?

A war file is just a jar file (like a zip archive) with a standard structure. Basic structure: WEB-INF/ - directory for application support lib/ - supporting jar files web.

What is the class loader and how .class will be loaded?

Class loaders are responsible for loading Java classes dynamically to the JVM (Java Virtual Machine) during runtime. They're also part of the JRE (Java Runtime Environment). Therefore, the JVM doesn't need to know about the underlying files or file systems in order to run Java programs thanks to class loaders.

How does a WAR file work?

A WAR file may be digitally signed in the same way as a JAR file in order to allow others to determine where the source code came from. There are special files and directories within a WAR file: The /WEB-INF directory in the WAR file contains a file named web. xml which defines the structure of the web application.


1 Answers

The selected answer is wrong. Servlet spec version 2.4 and 3.0 clearly states that WEB-INF/classes are loaded first and then 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 - section SRV.9.5, last paragraph

Servlet 3.0: http://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-oth-JSpec/servlet-3_0-final-spec.pdf - section 10.5, last paragraph

The Web application class loader must load classes from the WEB-INF/classes directory first, and then from library JARs in the WEB-INF/lib directory.

like image 159
Sajeev Avatar answered Sep 19 '22 17:09

Sajeev