I'm currently running my webapps on Tomcat 6 in production, and would like to evaluate running Tomcat in embedded mode.
Is there a good tutorial or other resource besides what's in the api documentation?
I'm currently running my webapps on Tomcat 6 in production, and would like to evaluate running Tomcat in embedded mode.
Is there a good tutorial or other resource besides what's in the api documentation?
Any reason to use Tomcat rather than Jetty, which is well documented for this use case and commonly used embedded? If you're simply looking for a Servlet container that you can embed, Jetty does this readily.
Code speaks for itself. See the pom.xml snippet and the class to run tomcat.
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
<version>6.0.18</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>coyote</artifactId>
<version>6.0.18</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>jasper</artifactId>
<version>6.0.18</version>
<scope>test</scope>
</dependency>
public class RunWebApplicationTomcat {
private String path = null;
private Embedded container = null;
private Log logger = LogFactory.getLog(getClass());
/**
* The directory to create the Tomcat server configuration under.
*/
private String catalinaHome = "tomcat";
/**
* The port to run the Tomcat server on.
*/
private int port = 8089;
/**
* The classes directory for the web application being run.
*/
private String classesDir = "target/classes";
/**
* The web resources directory for the web application being run.
*/
private String webappDir = "mywebapp";
/**
* Creates a single-webapp configuration to be run in Tomcat on port 8089. If module name does
* not conform to the 'contextname-webapp' convention, use the two-args constructor.
*
* @param contextName without leading slash, for example, "mywebapp"
* @throws IOException
*/
public RunWebApplicationTomcat(String contextName) {
Assert.isTrue(!contextName.startsWith("/"));
path = "/" + contextName;
}
/**
* Starts the embedded Tomcat server.
*
* @throws LifecycleException
* @throws MalformedURLException if the server could not be configured
* @throws LifecycleException if the server could not be started
* @throws MalformedURLException
*/
public void run(int port) throws LifecycleException, MalformedURLException {
this.port = port;
// create server
container = new Embedded();
container.setCatalinaHome(catalinaHome);
container.setRealm(new MemoryRealm());
// create webapp loader
WebappLoader loader = new WebappLoader(this.getClass().getClassLoader());
if (classesDir != null) {
loader.addRepository(new File(classesDir).toURI().toURL().toString());
}
// create context
// TODO: Context rootContext = container.createContext(path, webappDir);
Context rootContext = container.createContext(path, webappDir);
rootContext.setLoader(loader);
rootContext.setReloadable(true);
// create host
// String appBase = new File(catalinaHome, "webapps").getAbsolutePath();
Host localHost = container.createHost("localHost", new File("target").getAbsolutePath());
localHost.addChild(rootContext);
// create engine
Engine engine = container.createEngine();
engine.setName("localEngine");
engine.addChild(localHost);
engine.setDefaultHost(localHost.getName());
container.addEngine(engine);
// create http connector
Connector httpConnector = container.createConnector((InetAddress) null, port, false);
container.addConnector(httpConnector);
container.setAwait(true);
// start server
container.start();
// add shutdown hook to stop server
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
stopContainer();
}
});
}
/**
* Stops the embedded Tomcat server.
*/
public void stopContainer() {
try {
if (container != null) {
container.stop();
}
} catch (LifecycleException exception) {
logger.warn("Cannot Stop Tomcat" + exception.getMessage());
}
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public static void main(String[] args) throws Exception {
RunWebApplicationTomcat inst = new RunWebApplicationTomcat("mywebapp");
inst.run(8089);
}
public int getPort() {
return port;
}
}
This might help:
If you download the source package for Tomcat6.x, you get this class:
http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/startup/Catalina.html#main(java.lang.String[])
Which is an example of how to use the Embedd class: its a shell to stop|start a specific Tomcat installation. (I mean you can set up 'CATALINA_BASE' to point at an existing Tomcat installation).
If you compile this you can run like this:
java -D"catalina.base=%CATALINA_BASE%" -D"catalina.home=%CATALINA_HOME%" org.apache.catalina.startup.Catalina start
I'm not sure how to alter this code to shutdown the server yet though !!
There are a number of reasons why one might use Tomcat over Jetty:
Point #5 has been important in my work. For example, I can gain direct access to a JSPWiki instance via Tomcat, but it's completely inaccessible when using Jetty. I asked for a solution to that in 2007 and haven't yet heard an answer. So I finally gave up and began using Tomcat 6. I've looked into Glassfish and Grizzly, but so far Tomcat is (amazingly) the most stable and well-documented web container (which isn't saying much really).
I used the code snippet you wrote above.
but the server doesn't start. It sticks at Particular points.
Jul 10, 2010 12:15:12 PM org.apache.catalina.startup.Embedded start
INFO: Starting tomcat server
Jul 10, 2010 12:15:13 PM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.26
Jul 10, 2010 12:15:13 PM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-9999
Jul 10, 2010 12:15:13 PM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-9999
Nothing happened after this.
Thank You Mihir Parekh