Embedded Tomcat

08/28/2011

Earlier in the year, I posted a quick writeup on how to run an embedded Jetty instance. Today, I’m posting basically the same code showing how to run an embedded Tomcat instance. The embedded Tomcat API is much nicer since it matches closely the web.xml syntax. However, the embedded Tomcat instance takes much longer to startup.

package com.benmccann.webtemplate.frontend.server;

import java.net.URL;

import org.apache.catalina.Context;
import org.apache.catalina.core.AprLifecycleListener;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.deploy.FilterDef;
import org.apache.catalina.deploy.FilterMap;
import org.apache.catalina.startup.Tomcat;
import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;

import com.beust.jcommander.JCommander;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceFilter;

/**
 * @author Ben McCann (benmccann.com)
 */
public class WebServer {

  private final FrontendSettings webServerSettings;
  private final GuiceListener guiceListener;
  private final Tomcat tomcat;

  @Inject
  public WebServer(
      FrontendSettings webServerSettings,
      GuiceListener guiceListener) {
    this.webServerSettings = webServerSettings;
    this.guiceListener = guiceListener;
    this.tomcat = new Tomcat();
  }

  private FilterDef createFilterDef(String filterName, String filterClass) {
    FilterDef filterDef = new FilterDef();
    filterDef.setFilterName(filterName);
    filterDef.setFilterClass(filterClass);
    return filterDef;
  }
  
  private FilterMap createFilterMap(String filterName, String urlPattern) {
    FilterMap filterMap = new FilterMap();
    filterMap.setFilterName(filterName);
    filterMap.addURLPattern(urlPattern);
    return filterMap;
  }
  
  public void run() throws Exception {
    String appBase = ".";
    tomcat.setPort(webServerSettings.getPort());

    tomcat.setBaseDir("webapp");
    tomcat.getHost().setAppBase(appBase);

    String contextPath = "/";

    // Add AprLifecycleListener to give native speed boost
    // sudo apt-get install libtcnative-1
    StandardServer server = (StandardServer)tomcat.getServer();
    AprLifecycleListener listener = new AprLifecycleListener();
    server.addLifecycleListener(listener);

    Context context = tomcat.addWebapp(contextPath, appBase);
    context.addFilterDef(createFilterDef("guice", GuiceFilter.class.getName()));
    FilterDef struts2FilterDef = createFilterDef("struts2",
        StrutsPrepareAndExecuteFilter.class.getName());
    struts2FilterDef.addInitParameter("struts.devMode",
        Boolean.toString(webServerSettings.isDevModeEnabled()));
    context.addFilterDef(struts2FilterDef);
    context.addFilterMap(createFilterMap("guice", "/*"));
    context.addFilterMap(createFilterMap("struts2", "/*"));
    
    tomcat.start();
    tomcat.getServer().await();
  }

  public static void main(String[] args) throws Exception {
    FrontendSettings webServerSettings = new FrontendSettings();
    new JCommander(webServerSettings, args);
    
    Guice.createInjector(new FrontendModule(webServerSettings));
    
    Injector injector = Guice.createInjector();
    
    WebServer server = injector.getInstance(WebServer.class);
    server.run();
  }

}
Be Sociable, Share!