Embedded Apache Tomcat servlet container with Jakarta Servlet API, HTTP connectors, and lifecycle management for Java web applications
npx @tessl/cli install tessl/maven-org-apache-tomcat-embed--tomcat-embed-core@10.1.0Apache Tomcat Embedded Core provides a lightweight, embeddable servlet container for Java web applications. It includes the complete Jakarta Servlet 6.0 API implementation, HTTP/1.1 and HTTP/2 protocol support via Coyote connectors, the Catalina servlet engine with full lifecycle management, and the JULI logging framework. This library enables developers to embed a production-ready Tomcat server directly into Java applications without requiring external servlet container deployments.
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>10.1.41</version>
</dependency>// Embedded Tomcat startup
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
// Jakarta Servlet API
import jakarta.servlet.Servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
// Catalina core containers
import org.apache.catalina.Engine;
import org.apache.catalina.Host;
import org.apache.catalina.Wrapper;
import org.apache.catalina.connector.Connector;import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
public class EmbeddedTomcatExample {
public static void main(String[] args) throws LifecycleException {
// Create Tomcat instance
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.setBaseDir(new File("target/tomcat").getAbsolutePath());
// Add a simple context
Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
// Add a servlet
HttpServlet helloServlet = new HttpServlet() {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.println("<h1>Hello from Embedded Tomcat!</h1>");
}
};
Tomcat.addServlet(ctx, "helloServlet", helloServlet);
ctx.addServletMappingDecoded("/hello", "helloServlet");
// Start the server
tomcat.start();
tomcat.getServer().await();
}
}Apache Tomcat Embedded Core implements a modular architecture with distinct subsystems:
The core container hierarchy implements nested component management:
Each container implements the Lifecycle interface for consistent initialization, startup, shutdown, and destruction across the component hierarchy.
Protocol handlers manage network communication:
Connectors use ProtocolHandler implementations to process requests and generate responses through the Request and Response objects.
Request processing uses a chain-of-responsibility pattern:
Tomcat's Java Util Logging Implementation provides:
Complete implementation of Jakarta Servlet 6.0 specification including servlets, filters, listeners, request/response handling, sessions, async processing, and security constraints.
// Core servlet interface
public interface Servlet {
void init(ServletConfig config) throws ServletException;
void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
void destroy();
ServletConfig getServletConfig();
String getServletInfo();
}
// HTTP servlet base class
public abstract class HttpServlet extends GenericServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
}
// Servlet context interface
public interface ServletContext {
String getContextPath();
ServletContext getContext(String uripath);
RequestDispatcher getRequestDispatcher(String path);
void setAttribute(String name, Object object);
Object getAttribute(String name);
void log(String msg);
}Simplified API for programmatically creating and configuring embedded Tomcat instances with contexts, servlets, and connectors.
public class Tomcat {
public Tomcat();
public void setPort(int port);
public void setBaseDir(String basedir);
public void setHostname(String s);
// Add web applications
public Context addWebapp(String contextPath, String docBase);
public Context addContext(String contextPath, String docBase);
// Add servlets
public Wrapper addServlet(String contextPath, String servletName, String servletClass);
public Wrapper addServlet(String contextPath, String servletName, Servlet servlet);
public static Wrapper addServlet(Context ctx, String servletName, Servlet servlet);
// Lifecycle management
public void init() throws LifecycleException;
public void start() throws LifecycleException;
public void stop() throws LifecycleException;
public void destroy() throws LifecycleException;
// Access components
public Server getServer();
public Service getService();
public Engine getEngine();
public Host getHost();
public Connector getConnector();
public void setConnector(Connector connector);
}Container hierarchy (Server, Service, Engine, Host, Context, Wrapper) with lifecycle management, nested component relationships, and request processing pipelines.
// Base container interface
public interface Container extends Lifecycle {
String getName();
void setName(String name);
Container getParent();
void setParent(Container container);
void addChild(Container child);
Container findChild(String name);
Container[] findChildren();
Pipeline getPipeline();
Realm getRealm();
void setRealm(Realm realm);
}
// Context interface (web application)
public interface Context extends Container {
void setPath(String path);
String getPath();
void setDocBase(String docBase);
String getDocBase();
void addServletContainerInitializer(
ServletContainerInitializer sci, Set<Class<?>> classes);
void addApplicationListener(String listener);
void addServletMappingDecoded(String pattern, String name);
}
// Lifecycle interface
public interface Lifecycle {
void addLifecycleListener(LifecycleListener listener);
void removeLifecycleListener(LifecycleListener listener);
void init() throws LifecycleException;
void start() throws LifecycleException;
void stop() throws LifecycleException;
void destroy() throws LifecycleException;
LifecycleState getState();
String getStateName();
}Coyote connector architecture supporting HTTP/1.1, HTTP/2, and AJP protocols with configurable thread pools, connection limits, and protocol handlers.
public class Connector extends LifecycleMBeanBase {
public Connector();
public Connector(String protocol);
// Protocol configuration
public String getProtocol();
public String getScheme();
public void setScheme(String scheme);
public boolean getSecure();
public void setSecure(boolean secure);
// Network configuration
public int getPort();
public void setPort(int port);
public int getPortWithOffset();
// Protocol handler properties (delegated via reflection)
// Use setProperty to configure: maxThreads, connectionTimeout, maxConnections, etc.
public boolean setProperty(String name, String value);
public Object getProperty(String name);
// Request/response handling
public Request createRequest();
public Response createResponse();
}Comprehensive authentication support including BASIC, DIGEST, FORM, CLIENT-CERT authenticators, realm implementations for user/role management, and Jakarta Authentication (JASPIC) integration.
// Realm interface for authentication
public interface Realm {
Principal authenticate(String username, String credentials);
Principal authenticate(String username, String digest, String nonce,
String nc, String cnonce, String qop, String realm, String md5a2);
Principal authenticate(X509Certificate[] certs);
Principal authenticate(GSSContext gssContext, boolean storeCreds);
boolean hasRole(Wrapper wrapper, Principal principal, String role);
void setCredentialHandler(CredentialHandler credentialHandler);
CredentialHandler getCredentialHandler();
}
// JASPIC ServerAuthModule
public interface ServerAuthModule {
void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy,
CallbackHandler handler, Map<String,Object> options) throws AuthException;
AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject,
Subject serviceSubject) throws AuthException;
AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject)
throws AuthException;
void cleanSubject(MessageInfo messageInfo, Subject subject) throws AuthException;
}HTTP session tracking with configurable persistence stores, clustering support, session ID generation, and timeout management.
// Manager interface for session management
public interface Manager {
Context getContext();
void setContext(Context context);
// Session operations
void add(Session session);
Session createSession(String sessionId);
Session findSession(String id) throws IOException;
void remove(Session session);
void remove(Session session, boolean update);
// Session configuration
int getMaxInactiveInterval();
void setMaxInactiveInterval(int interval);
int getSessionIdLength();
void setSessionIdLength(int length);
// Statistics
int getActiveSessions();
long getExpiredSessions();
void setExpiredSessions(long expiredSessions);
int getRejectedSessions();
}
// Session interface
public interface Session {
String getId();
void setId(String id);
Manager getManager();
void setManager(Manager manager);
long getCreationTime();
long getLastAccessedTime();
int getMaxInactiveInterval();
void setMaxInactiveInterval(int interval);
void access();
void expire();
}Request processing pipeline with valves for cross-cutting concerns including access logging, authentication, compression, rewriting, and custom request/response processing.
// Valve interface
public interface Valve {
Valve getNext();
void setNext(Valve valve);
void invoke(Request request, Response response) throws IOException, ServletException;
boolean isAsyncSupported();
void backgroundProcess();
}
// Pipeline interface
public interface Pipeline extends Contained {
Valve getBasic();
void setBasic(Valve valve);
void addValve(Valve valve);
Valve[] getValves();
void removeValve(Valve valve);
Valve getFirst();
boolean isAsyncSupported();
}
// Common valve types
public abstract class ValveBase extends LifecycleMBeanBase implements Valve {
protected Valve next;
public Valve getNext();
public void setNext(Valve valve);
public abstract void invoke(Request request, Response response)
throws IOException, ServletException;
}Resource management system for serving static content, loading classes, and accessing JAR files with support for multiple resource sets, caching, and virtual directories.
// WebResourceRoot interface
public interface WebResourceRoot extends Lifecycle {
WebResource getResource(String path);
WebResource getClassLoaderResource(String path);
WebResource[] getResources(String path);
WebResource[] getClassLoaderResources(String path);
WebResource[] listResources(String path);
// Resource set management
void addPreResources(WebResourceSet webResourceSet);
void addJarResources(WebResourceSet webResourceSet);
void addPostResources(WebResourceSet webResourceSet);
void createWebResourceSet(ResourceSetType type, String webAppMount,
String base, String archivePath, String internalPath);
// Configuration
void setCachingAllowed(boolean cachingAllowed);
boolean isCachingAllowed();
void setCacheTtl(long ttl);
long getCacheTtl();
}
// WebResource interface
public interface WebResource {
long getLastModified();
String getLastModifiedHttp();
boolean exists();
boolean isVirtual();
boolean isDirectory();
boolean isFile();
String getName();
long getContentLength();
String getCanonicalPath();
boolean canRead();
String getWebappPath();
InputStream getInputStream();
byte[] getContent();
}Tomcat's Java Util Logging Implementation providing per-classloader log isolation, configurable handlers, formatters, and integration with java.util.logging.
// JULI Log interface (commons-logging compatible)
public interface Log {
boolean isDebugEnabled();
boolean isErrorEnabled();
boolean isFatalEnabled();
boolean isInfoEnabled();
boolean isTraceEnabled();
boolean isWarnEnabled();
void trace(Object message);
void trace(Object message, Throwable t);
void debug(Object message);
void debug(Object message, Throwable t);
void info(Object message);
void info(Object message, Throwable t);
void warn(Object message);
void warn(Object message, Throwable t);
void error(Object message);
void error(Object message, Throwable t);
void fatal(Object message);
void fatal(Object message, Throwable t);
}
// LogFactory for obtaining Log instances
public class LogFactory {
public static Log getLog(Class<?> clazz);
public static Log getLog(String name);
}Comprehensive utility libraries including HTTP parsing, byte buffers, character encoding, networking utilities, threading utilities, URI encoding, MIME type handling, and collection utilities.
// ByteChunk for efficient byte buffer management
public final class ByteChunk implements Cloneable, Serializable {
public void setBytes(byte[] b, int off, int len);
public byte[] getBytes();
public int getStart();
public int getEnd();
public int getLength();
public void recycle();
public void append(byte b) throws IOException;
}
// MessageBytes for efficient string/byte conversion
public final class MessageBytes implements Cloneable, Serializable {
public static final int T_NULL = 0;
public static final int T_STR = 1;
public static final int T_BYTES = 2;
public static final int T_CHARS = 3;
public void setString(String s);
public String toString();
public ByteChunk getByteChunk();
public CharChunk getCharChunk();
public int getType();
}
// B2CConverter for byte-to-char encoding conversion
public class B2CConverter {
public B2CConverter(Charset charset);
public void convert(ByteChunk bb, CharChunk cb) throws IOException;
public void recycle();
}Types used across multiple capabilities:
// LifecycleException
public final class LifecycleException extends Exception {
public LifecycleException();
public LifecycleException(String message);
public LifecycleException(Throwable throwable);
public LifecycleException(String message, Throwable throwable);
}
// ServletException (Jakarta Servlet API)
public class ServletException extends Exception {
public ServletException();
public ServletException(String message);
public ServletException(String message, Throwable rootCause);
public ServletException(Throwable rootCause);
public Throwable getRootCause();
}
// LifecycleState enum
public enum LifecycleState {
NEW,
INITIALIZING,
INITIALIZED,
STARTING_PREP,
STARTING,
STARTED,
STOPPING_PREP,
STOPPING,
STOPPED,
DESTROYING,
DESTROYED,
FAILED;
public boolean isAvailable();
public String getLifecycleEvent();
}All major Tomcat components implement a consistent lifecycle:
Valves in pipelines process requests sequentially, with each valve deciding whether to continue the chain or terminate processing.
Request and Response facades protect internal Catalina objects from direct access by application code, providing security and encapsulation.
For applications migrating from Java EE to Jakarta EE:
javax.servlet to jakarta.servlet