Getting started with Embedded Tomcat
The purpose of this post is to help you get started with Tomcat embedded, and will cover the following:
- Starting a new Mavenized Tomcat project
- Deploy a simple servlet to the embedded Tomcat process
Create a Tomcat Maven Project
The first step to getting started is to create a new project. You can do this by using a maven archetype, or by creating the directory structure that you need. If you want to use an archetype to generate the structure for you, execute the following:
mvn archetype:generate -DgroupId=io.github.csutherl.tomcat
-DartifactId=HelloApplication
-DarchetypeArtifactId=maven-archetype-webapp
-DinteractiveMode=false
The maven-archetype-webapp archetype creates a directory structure that looks like this:
|----HelloApplication
| |----pom.xml
| |----src
| | |----main
| | | |----resources
| | | |----webapp
| | | | |----index.jsp
| | | | |----WEB-INF
| | | | | |----web.xml
I’m all for using tools to automatically do things for me, but in reality we just want to create a simple servlet and start it up with maven so we don’t really need all of that fluff. We can manually create the directory structure necessary which will mirror the one generated by Maven by using the following command. This will build the structure we need while leaving out the web.xml and JSP stuff that’s generated by the archetype.
mkdir -p HelloApplication/src/main/java/io/github/csutherl/tomcat/servlets/
cd HelloApplication
After we have a working directory for the application we can create the application and servlet code along with the maven pom.
Create and Deploy the Servlet
To create the application code which uses embedded tomcat we place this java class in a file (named HelloApplication.java) within the tomcat package directory:
package io.github.csutherl.tomcat;
import io.github.csutherl.tomcat.servlets.HelloServlet;
import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
public class HelloApplication {
public static void main(String[] args) throws Exception {
// Get an instance of Tomcat
Tomcat tomcat = new Tomcat();
// Add an empty context
Context ctx = tomcat.addContext("", null);
// Get an instance of the servlet and add a servlet mapping
Tomcat.addServlet(ctx, "hello", new HelloServlet());
ctx.addServletMapping("/hello", "hello");
// Start the tomcat instance
tomcat.start();
// Wait for a control-C to stop the process to allow for testing
tomcat.getServer().await();
}
}
The code above uses a servlet, HelloServlet, defined by the java code below. This code should be placed in a file named HelloServlet.java which should be located within the servlets package directory.
package io.github.csutherl.tomcat.servlets;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h3>Hello!!</h3>");
}
}
Now that we have application code and a servlet to deploy, we need to setup the pom so that we can compile and run this application. My pom looks like this:
<?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>io.github.csutherl.tomcat</groupId>
<artifactId>hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>hello</name>
<description>Hello World for Embedded Tomcat</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<tomcat-version>8.0.36</tomcat-version>
</properties>
<dependencies>
<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>
<!-- The build portion is not necessary, but it saves you from using The
exec.MainClass system property, such as:
mvn exec:java -Dexec.mainClass=io.github.csutherl.tomcat.HelloApplication -->
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>io.github.csutherl.tomcat.HelloApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
OK! Now we can compile and run the application. To do so, execute the following:
mvn clean install exec:java
After running the above commands you will see the code being compiled and executed, which looks something like the following for a successful build:
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building hello 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> exec-maven-plugin:1.2.1.jbossorg-3:java (default-cli) > validate @ hello >>>
[INFO]
[INFO] <<< exec-maven-plugin:1.2.1.jbossorg-3:java (default-cli) < validate @ hello <<<
[INFO]
[INFO] --- exec-maven-plugin:1.2.1.jbossorg-3:java (default-cli) @ hello ---
Feb 02, 2017 9:42:52 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Feb 02, 2017 9:42:52 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFO: Using a shared selector for servlet write/read
Feb 02, 2017 9:42:52 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Feb 02, 2017 9:42:52 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.36
Feb 02, 2017 9:42:52 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Note: I used the call to tomcat.getServer().await() so that the container process continues running until you stop it.
You can test the serlvet in a seperate terminal with curl (or your browser) like this:
curl http://localhost:8080/hello
And that’s it! You have created an embedded tomcat application that is serving a simple servlet.
Leave a Comment