Unlock Tomcat’s Secrets: Deep Dive into Its Architecture, Design Patterns, and Class Loading

This article provides a comprehensive technical walkthrough of Tomcat, covering its connector and container architecture, lifecycle management, key design patterns such as Composite and Template Method, custom class‑loading mechanisms, hot‑reload process, and includes essential code snippets and diagrams for developers.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Unlock Tomcat’s Secrets: Deep Dive into Its Architecture, Design Patterns, and Class Loading

Understanding Tomcat Architecture

Tomcat is a mature Java HTTP server that implements the Servlet container. Its core responsibilities are split into Connectors (network I/O) and Containers (Servlet management).

Connector Components

Endpoint

– low‑level socket listener (NIO, NIO2, APR). Processor – parses the HTTP request and creates Request / Response objects. Adapter (CoyoteAdapter) – converts Tomcat’s internal Request to a ServletRequest and invokes the container pipeline.

Container Hierarchy

Four container types form a tree: Engine → Host → Context → Wrapper. All implement the Container interface and inherit lifecycle management.

Lifecycle Management

Every container implements Lifecycle with the methods init(), start(), stop(), and destroy(). The abstract class LifecycleBase provides a template method that handles state transitions and fires LifecycleEvent listeners (Observer pattern).

Design Patterns Used

Composite – container tree.

Template Method – lifecycle handling and Tomcat’s init/start sequence.

Observer – lifecycle events.

Adapter – Connector → Container.

Chain of Responsibility – Pipeline/Valve processing.

Class Loading in Tomcat

Tomcat uses a custom WebAppClassLoader that breaks the standard parent‑delegation model: it first attempts to load a class from the web‑app’s /WEB-INF/classes and /WEB-INF/lib, then delegates to its parent. This allows each web application to have its own class space while still sharing common libraries via SharedClassLoader and CatalinaClassLoader.

Hot Reload

Each Context has its own class loader. The ContainerBackgroundProcessor runs periodically, detects changed class files, destroys the old Context, creates a new class loader, and re‑initialises the web application.

Request Flow

When a request arrives:

The appropriate Connector (e.g., HTTP/1.1 on port 8080) receives the socket data. Endpoint reads the bytes and hands them to a Processor.

The Processor builds a Tomcat Request object and passes it to the Adapter.

The Adapter converts the request to a ServletRequest and calls the container’s pipeline:

connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);

The pipeline consists of a chain of Valve objects (Chain of Responsibility). The final valve invokes the target Wrapper, which creates the servlet instance and calls its service() method.

ProtocolHandler and Pipeline

The ProtocolHandler abstracts the network protocol. It composes Endpoint and Processor into a single component. Each container owns a Pipeline that holds a linked list of Valve objects. The first valve is invoked by the adapter, and each valve calls getNext().invoke() to continue the chain.

Mapper – Locating the Target Servlet

The Mapper component stores the mapping between host names, context paths, and servlet URL patterns. During request processing it resolves the request URL to a specific Wrapper (the servlet) by traversing this map.

JVM Class‑Loader Hierarchy

Standard JVM loaders: BootstrapClassLoader – loads core JRE classes (rt.jar). ExtClassLoader – loads JRE extensions ( $JAVA_HOME/jre/lib/ext). AppClassLoader – loads application classpath.

Tomcat adds: WebAppClassLoader – one instance per web application, providing isolation. SharedClassLoader – parent of each WebAppClassLoader, used for libraries shared across applications. CatalinaClassLoader (and optionally CommonClassLoader) – loads Tomcat’s own classes, keeping them separate from web apps.

WebAppClassLoader – Breaking Parent Delegation

Its loadClass() method first tries to find the class in the web app’s resources; if not found, it delegates to the parent. This prevents a web app from accidentally overriding JRE core classes while still allowing the app to load its own versions of libraries.

public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    synchronized (getClassLoadingLock(name)) {
        // 1. Check if already loaded by this loader
        Class<?> c = findLoadedClass(name);
        if (c == null) {
            // 2. Try parent (ExtClassLoader) to protect JRE classes
            try {
                c = getJavaseClassLoader().loadClass(name);
            } catch (ClassNotFoundException ignored) {}
        }
        if (c == null) {
            // 3. Load from web‑app directory
            c = findClass(name);
        }
        if (c == null) {
            // 4. Fallback to system AppClassLoader
            c = Class.forName(name, false, parent);
        }
        if (c == null) throw new ClassNotFoundException(name);
        if (resolve) resolveClass(c);
        return c;
    }
}

Embedded Tomcat Debugging Example

Embedded Tomcat debugging example: https://github.com/UniqueDong/tomcat-embedded
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsJavaBackend DevelopmentClass LoaderWeb serverTomcat
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.