Embedded Tomcat
last modified January 10, 2023
In this tutorial, we show how work with embedded Tomcat server. Tomcat can be run in embedded mode; it means that it is not necessary to build a WAR file and deploy it in a standalone Tomcat server. The examples in this tutorial are built with Maven.
Tomcat
Apache Tomcat is an open source implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies.
Apache Maven is a software project management and comprehension tool.
The project is described in an XML file called pom.xml
. It contains
project dependencies on other external modules and components, the build order, directories,
and required plug-ins.
Creating a servlet
In the following example, we create a command line Java application with embedded Tomcat server. The application attaches a simple servlet.
The figure shows the project structure in NetBeans. Notice that we use a Java Maven console application, not a Maven web application.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zetcode</groupId> <artifactId>EmbeddedTomcatEx</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <tomcat.version>9.0.0.M6</tomcat.version> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-logging-juli</artifactId> <version>${tomcat.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>appassembler-maven-plugin</artifactId> <version>1.1.1</version> <configuration> <assembleDirectory>target</assembleDirectory> <programs> <program> <mainClass>com.zetcode.embedded.EmbeddedTomcatEx</mainClass> <name>webapp</name> </program> </programs> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>assemble</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
The Maven pom.xml
contains dependencies for the embedded Tomcat server
and the assembler plugin, which builds the application. Dependencies for JSP container
are not included in this application, since we only have a servlet.
package com.zetcode.embedded; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.Writer; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; public class EmbeddedTomcatEx { public static void main(String[] args) throws LifecycleException, InterruptedException, ServletException { Tomcat tomcat = new Tomcat(); tomcat.setPort(8082); Context ctx = tomcat.addContext("/", new File(".").getAbsolutePath()); Tomcat.addServlet(ctx, "Embedded", new HttpServlet() { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Writer w = resp.getWriter(); w.write("Embedded Tomcat servlet.\n"); w.flush(); w.close(); } }); ctx.addServletMapping("/*", "Embedded"); tomcat.start(); tomcat.getServer().await(); } }
The EmbeddedTomcatEx
is a Java console application, which includes
an embedded Tomcat server.
Tomcat tomcat = new Tomcat(); tomcat.setPort(8082);
Tomcat is started on port 8082. The default port is 8080; NetBeans uses 8084 for its built-in Tomcat server. We chose another port so that there is not collision.
Context ctx = tomcat.addContext("/", new File(".").getAbsolutePath());
Each application is mapped to a context. With the addContext
method,
we create an application that does not support JSP files and has no web.xml
file. We use a root context path and a current working directory for the document base.
Tomcat.addServlet(ctx, "Embedded", new HttpServlet() { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Writer w = resp.getWriter(); w.write("Embedded Tomcat servlet.\n"); w.flush(); w.close(); } });
A new servlet is added with the addServlet
method. The servlet simply
responds with some ASCII text.
ctx.addServletMapping("/*", "Embedded");
The servlet mappping controls how the servlet, named Embedded, is accessed. For our example, any URLs end up calling our servlet.
tomcat.start(); tomcat.getServer().await();
Tomcat server is started.
$ curl localhost:8082/ Embedded Tomcat servlet.
We run the application and test it with the curl
tool.
JSP file
In the second example, we use embedded Tomcat server to serve a JSP file.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zetcode</groupId> <artifactId>EmbeddedTomcatEx2</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <tomcat.version>9.0.0.M6</tomcat.version> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-logging-juli</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper-el</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jsp-api</artifactId> <version>${tomcat.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>appassembler-maven-plugin</artifactId> <version>1.1.1</version> <configuration> <assembleDirectory>target</assembleDirectory> <programs> <program> <mainClass>com.zetcode.embedded.EmbeddedTomcatEx2</mainClass> <name>webapp</name> </program> </programs> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>assemble</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <name>EmbeddedTomcatEx2</name> </project>
In this pom.xml
file, we also include dependencies for
embedded Tomcat JSP container: tomcat-jasper
, tomcat-jasper-el
,
and tomcat-jsp-api
.
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <title>JSP file</title> <meta charset="UTF-8"> </head> <body> <p> This is a simple JSP file. </p> </body> </html>
This is a simple JSP file to be served by embedded Tomcat server.
package com.zetcode.embedded; import javax.servlet.ServletException; import java.io.File; import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; public class EmbeddedTomcatEx2 { public static void main(String[] args) throws LifecycleException, InterruptedException, ServletException { String docBase = "src/main/webapp/"; Tomcat tomcat = new Tomcat(); tomcat.setPort(8082); tomcat.addWebapp("/", new File(docBase).getAbsolutePath()); tomcat.start(); tomcat.getServer().await(); } }
The application serves a JSP file. The file is located in the src/main/webapp
subdirectory.
tomcat.addWebapp("/", new File(docBase).getAbsolutePath());
This time we use the addWebapp
to add our application
to the Tomcat server.
$ curl localhost:8082/ <!DOCTYPE html> <html> <head> <title>JSP file</title> <meta charset="UTF-8"> </head> <body> <p> This is a simple JSP file. </p> </body> </html>
We get this when we access the application.
This was the Embedded Tomcat tutorial. With the embedded Tomcat, we served a servlet and a JSP file. We have used Apache Tomcat, Maven, and NetBeans. You might also want to check some related tutorials: Jersey application with embedded Jetty, Jetty tutorial, Java tutorial, or SQL Query tag utorial.