Inside Tomcat: Architecture, Lifecycle, Connectors, and Asynchronous Processing Explained

This article provides a comprehensive technical overview of Apache Tomcat, covering its role as a Java EE servlet container, internal components such as Server, Service, Connector, and Container, lifecycle management, startup sequence, deployment configuration, JSP engine, connector types, NIO processing, Comet, and asynchronous servlet handling.

Senior Brother's Insights
Senior Brother's Insights
Senior Brother's Insights
Inside Tomcat: Architecture, Lifecycle, Connectors, and Asynchronous Processing Explained

What Is Tomcat?

Tomcat is an open‑source Java web application server that implements part of the Java EE specifications, including Servlet, JSP, JSTL, and WebSocket. It provides the core web container needed for Java EE applications, while other specifications (EJB, JPA, JMS, etc.) require additional containers.

The Java EE container landscape shows that Tomcat and Jetty only implement the mandatory Servlet and JSP specifications; developers must add other libraries for additional functionality. GlassFish implements the full Java EE stack and is often used for exploring the latest specifications.

Servlet Container Structure

Tomcat consists of three main parts: Server , Service , and Connector , each built around a Container hierarchy.

Server manages multiple Services and listens on the shutdown port (default 8005) to stop the whole container.

Service groups a set of Connectors and a single Container (Catalina) that hosts web applications.

Connector bridges external protocols (HTTP, AJP) to the internal Container.

Container (Catalina) manages the servlet lifecycle and delegates to sub‑containers such as Engine, Host, Context, and Wrapper.

Key Sub‑components

Engine : top‑level servlet container, can contain multiple Host elements.

Host : virtual host that creates Context for each web app.

Context : represents a single web application, holds multiple Wrapper objects.

Wrapper : the lowest level, wraps an individual servlet instance.

Loader : encapsulates a Java ClassLoader for loading classes.

Realm : provides authentication and role management.

JMX : Java Management Extensions for remote monitoring.

Jasper : JSP compilation engine.

Session : session creation, persistence, and clustering support.

Pipeline and Valve : a chain of processing elements that can be customized.

Naming : JNDI support for resource lookup.

Lifecycle Management

All Tomcat components inherit from ContainerBase, which defines twelve lifecycle states (e.g., NEW, INITIALIZING, INITIALIZED, STARTING, STARTED, STOPPING, STOPPED, DESTROYED). Each component implements methods such as initInternal(), startInternal(), stopInternal(), and destroyInternal() to transition between states.

During initialization, the container checks its current state; if it is not NEW , a LifecycleException is thrown. Successful initialization moves the state to INITIALIZED , while failures set it to FAILED .

Listeners can be registered in server.xml to react to lifecycle events. Configuration listeners such as EngineConfig, HostConfig, and ContextConfig decouple configuration logic from the container.

Configuration Listeners

EngineConfig : logs startup and shutdown events.

HostConfig : scans $catalina.base/webapps/ for applications, parses META-INF/context.xml, and creates StandardContext objects.

ContextConfig : merges web.xml files, processes WEB-INF/lib/*.jar for web-fragment.xml, and builds the final WebXml model.

Tomcat Startup Process

The startup begins with the start.sh script, which invokes Bootstrap.main(). Bootstrap loads the Catalina class and calls its load() and start() methods. load() uses Digester to parse conf/server.xml, creating the component hierarchy (Server → Service → Engine → Host → Context → Wrapper). After parsing, StandardServer calls init() and start() on the created components.

Once started, StandardServer listens on the shutdown port (default 8005). Receiving a shutdown command triggers stop() and destroy(), which cascade through the component tree. A JVM shutdown hook also ensures graceful termination.

List<Future<Void>> results = new ArrayList<Future<Void>>();
for (int i = 0; i < children.length; i++) {
    results.add(startStopExecutor.submit(new StartChild(children[i])));
}
boolean fail = false;
for (Future<Void> result : results) {
    try {
        result.get();
    } catch (Exception e) {
        log.error(sm.getString("containerBase.threadedStartFailed"), e);
        fail = true;
    }
}

Web Application Deployment

Key directories: catalina.home: Tomcat installation directory. catalina.base: Working directory (defaults to user.dir).

Deployment steps (via server.xml and context files):

Define a Host element with appBase (default $catalina.base/webapps/).

Define a Context element with docBase pointing to the web app location.

Custom context files can be placed under $catalina.base/EngineName/HostName/.

HostConfig watches the appBase directory, parses each application's META-INF/context.xml, creates a StandardContext, and adds it to the host. ContextConfig processes global config/context.xml, host‑level defaults, and finally the application‑specific META-INF/context.xml. It also merges web.xml files in a similar order.

Servlet Lifecycle

Request arrives and is mapped to a servlet.

If the servlet instance does not exist, Tomcat loads the class, creates an instance, and calls init().

Tomcat creates Request and Response objects and invokes the servlet’s service() method, which delegates to doGet, doPost, etc.

The servlet processes business logic and writes the result to the response.

When the server shuts down, Tomcat calls destroy() on the servlet.

load‑on‑startup : A non‑negative value loads the servlet at application startup; the smaller the number, the higher the priority. A negative value or omission defers loading until the servlet is first requested.

single‑thread‑model : Creates a new servlet instance per request but does not guarantee thread safety; modern practice is to avoid this model.

Connector Types

Tomcat supports three connector implementations, selectable in server.xml:

BIO (blocking I/O) – uses java.io streams.

NIO (non‑blocking I/O) – uses java.nio with selector‑based multiplexing.

APR (Apache Portable Runtime) – native library accessed via JNI, offering advanced features such as sendfile, epoll, and OpenSSL.

Key connector parameters include support for I/O polling, maximum poll size, request header parsing, request body handling, and response writing. NIO relies on three thread types:

Acceptor : accepts new sockets and registers them for read events.

Poller : runs the selector loop, creates Http11NioProcessor for readable sockets.

CoyoteAdapter : adapts the connector to the container pipeline.

Comet (Long‑Polling) Support

To implement Comet, a servlet must implement the CometProcessor interface. The lifecycle includes begin, read, end, and error callbacks, with notes on thread‑safety and proper session closure.

Asynchronous Servlet Processing

Traditional flow: request → servlet → business logic → response → thread ends.

Asynchronous flow:

Client sends a request.

Tomcat allocates a thread to invoke the servlet.

The servlet calls request.startAsync(), stores the AsyncContext, and returns.

The original thread is released; the response remains open.

A background thread (e.g., from a thread pool) completes the business logic using the saved AsyncContext and writes the response.

Client receives the response.

Asynchronous processing is useful for long‑running operations such as slow database queries or external API calls, preventing servlet threads from being blocked and improving scalability.

Supported async events: onStartAsync: triggered when startAsync() is called. onComplete: after complete() is invoked. onError: on processing exceptions. onTimeout: when the request times out.

After onError or onTimeout, the container immediately calls onComplete, after which the request and response objects must no longer be used.

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.

JavaConnectorAsynchronousnioLifecycleWeb serverServletTomcat
Senior Brother's Insights
Written by

Senior Brother's Insights

A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.

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.