About     Search     Feed

Nilesh D Kapadia


Music     Twitter     Github

Embedding Apache Tomcat 7.0

Apache Tomcat 7.0 now has a beta release out. One of it’s features is improved support for embedding. I have been embedding Jetty successfully in various projects, so I was hoping that Tomcat’s support for embedding was on par with Jetty’s. So far, Tomcat 7.0’s embedding API is quite easy to use and has been working well. However, I did not find any documentation on how to actually use it, so it took a small bit of digging to figure out how.

Details

The one suggestion I read was to look at the test cases, because they used embedded Tomcat. So I checked out the source code, and found TomcatBaseTest which was an abstract class that tests were subclassing which provided a running embedded Tomcat. The org.apache.catalina.startup.Tomcat class is what you need to use. After setting various settings, adding the application(s), you then call the start() to start Tomcat. Note that start() does not block, so if you exit your main method, Tomcat will quit.

Like it’s non-embedded version, embedded Tomcat needs to create a work directory for temporary files. You specify a base directory which the work directory will be created in. I believe this base directory is the equivalent to Tomcat home directory. Use the setBaseDir(String baseDir) method to set this. Looking at the source for Tomcat.initBaseDir() method, it looks like if you don’t set it using this method, it will try to obtain this by trying:

  1. From the catalina.base system property
  2. Failing that, from the catalina.base system property
  3. Create a temp directory using user.dir system property as a base and tomcat.PORT_NUMBER as the temp directory it creates (replacing PORT_NUMBER with the actual port number.

You can set a port number with setPort(int port). This defaults to 8080 if not set.

To add an application, use the addWebapp(String contextPath, String baseDir) method, setting the webapp’s context path and specifying the location of the webapp folder for baseDir.

Once you are configured, you can call the start() method. Then you need to make sure your app doesn’t exit, the simplest way is to do an infinite loop, e.g. while(true) { Thread.sleep(999999999); }

Necessary JAR files

From the Tomcat 7.0.2 distribution, I put the following jar files in my classpath (not sure if all of them are necessary):

Notes:

Example

Here is a little example app that assumes you have a webapp (WEB-INF with a web.xml in it) in the folder examplewebapp:

import java.io.File;
import java.io.IOException;
import java.lang.InterruptedException;

import javax.servlet.ServletException;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;

public class TomcatEmbedExample {

    public static void main(String[] args) 
        throws IOException, ServletException, 
               LifecycleException, InterruptedException {

        String currentDir = new File(".").getCanonicalPath();
        String tomcatDir = currentDir + File.separatorChar + "tomcat";
        String webRoot = currentDir + File.separatorChar + "examplewebapp";

        Tomcat tomcat = new Tomcat();
        tomcat.setBaseDir(tomcatDir);
        tomcat.setPort(4040);
        tomcat.addWebapp("/examplewebapp", webRoot);
        // or we could do this for root context:
        // tomcat.addWebapp("/", webRoot);
        tomcat.start();

        while (true) {
            Thread.sleep(999999999);
        }
    }

}

Ideas on what this can be used for

This has replace embedded Jetty as my development server. I run it inside of a debugger (Eclipse), and Java hot code replace works nicely. One thing that I am experimenting with is monitoring specific files to know when to restart the app. I am currently using JNotify to monitor file changes, and restart the app when XML files or other configuration files change that need a restart to get applied. It is working great so far, and I no longer have to manually restart the server or sacrifice Java hot code replace.

© 2017 Nilesh D Kapadia