Why Does Tomcat Load Your src Classes Before JARs? Unveiling the Class Loader Hierarchy
This article explains the JVM and Tomcat class‑loading mechanisms, describes the parent‑delegation model, outlines the specific loaders Tomcat creates at startup, and shows why classes compiled from a project's src folder are preferred over those packaged in JARs.
1. Class Loading
In the JVM, classes are not loaded all at once; they are loaded step‑by‑step as needed.
During JVM startup, different class loaders load different classes, and when user code requests additional classes, the loading mechanism brings them into the JVM and keeps them cached for frequent use.
Choosing which class loader to use and where it loads classes from are important JVM concepts.
2. JVM Class Loading
The JVM adopts the parent‑delegation mechanism as shown in the diagram below.
The JVM includes several built‑in class loaders:
BootstrapClassLoader (bootstrap loader)
ExtClassLoader (extension loader)
AppClassLoader (application loader)
CustomClassLoader (user‑defined loader)
Different loaders load different classes, and a class loaded by one loader cannot be used directly by another.
When a user requests a class, the JVM follows these steps:
The user’s loader delegates the request to its parent, up to the top of the loader hierarchy.
The top‑most loader attempts to load the class from its designated location; if it fails, it passes the request down.
If no loader can find the class, a ClassNotFoundException is thrown.
Consequently, if the same class exists both in a directory listed in CLASSPATH and in the working directory, the one in CLASSPATH is loaded first.
3. Tomcat Class Loading
Tomcat’s class‑loading differs slightly from the standard JVM model, as illustrated below.
When Tomcat starts, it creates several class loaders:
Bootstrap Loader : loads classes required for JVM startup and standard extensions located under jre/lib/ext.
System Loader : loads Tomcat startup classes such as bootstrap.jar, typically defined in catalina.bat or catalina.sh, located in CATALINA_HOME/bin.
Common Loader : loads classes shared by Tomcat and web applications, found in CATALINA_HOME/lib (e.g., servlet-api.jar).
Webapp Loader : each deployed web application gets its own loader, which loads classes from WEB-INF/lib (JAR files) and WEB-INF/classes (compiled classes).
When an application needs a class, Tomcat follows this loading order:
Bootstrap loader
System loader
Webapp loader loading from WEB-INF/classes Webapp loader loading from WEB-INF/lib Common loader loading from
CATALINA_HOME/lib4. Extended Discussion
Understanding Tomcat’s class‑loading explains why Java files placed in Eclipse’s src folder are loaded before classes from external JARs: during Tomcat startup, source files and JSPs are compiled into WEB-INF/classes, giving them higher priority than JARs located in WEB-INF/lib.
If different versions of the same JAR are placed in both CATALINA_HOME/lib and WEB-INF/lib, or if multiple applications share duplicate JARs, class‑loading conflicts may arise, leading to ClassNotFoundException errors.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
