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
Both the WEB-INF/lib/*.jar
files and the WEB-INF/classes
directory are in the same ClassLoader. It would be as if you started an application with all the jars listed in the ClassPath. As a class name needs to be resolved, the ClassLoader will find the first class that matches from its resources. The exact order it searches in is nondeterministic--it depends on the platform.
Java Packages were designed to address the problem of name clashes such as what you described. It is never a good idea to deliberately name a class the same as what is bundled in its own jar file. The better solution would be to extend the class and use the new version in your code. If you need to alter functionality of that class, then you might look into the black magic of Java Aspect Oriented Programming.
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.
This answer was incorrect but cannot be deleted because it is the accepted answer. See @Sajeev's answer below.
It depends on the container that deploys the war file. From my experiences, WEB-INF/classes location is always before lib/ on the classpath of a classloader for application context.
Classes are loaded right after the deployer expands the war into the container. Usually when a context loader listener servlet is loaded and the rest of the application with it. It can be done in many ways such as by a reference to default servlet or loading spring context etc.
So that WEB-INF/classes/com/acme/Bunny.class should be loaded first afaik.
The answer depends entirely on the concrete class loader hierarchy in use. While the JVM will provide a system class loader, Java EE application servers will typically use custom ClassLoader implementations to isolate classes loaded in separate modules and applications, and to enforce security concerns.
The ClassLoader API does not impose any rules on how concrete implementations resolve class requests. However, the intent of the WEB-INF/lib directory is to allow bundling of app-specific libraries. I suspect most people would expect the jar files in the lib directory to be searched AFTER the root contents of the jar file.
I'm not aware that the Java EE specifications establish any such guarantee though, and the interface and documentation for the abstract ClassLoader class certainly doesn't.
So, hypothetically, you could have a web container that would end up returning Bunny.class from the jar file instead of the one from the root hierarchy of the war file.
You seem to be conflating two different senses of "before".
Classes are loaded in the order they are used. This is temporal, and is the more correct use of "before". If Foo is used before Bar then it'll be loaded before Bar.
You're also talking about whether classes/com/acme/Bunny.class will be loaded "before" acme.jar's com/acme/Bunny.class. The second one won't be loaded at all. The classloader will look for the first instance of com/acme/Bunny.class on the classpath, find the one in classes, and stop looking.