Apache Tomcat 6

How to Install & Configure

Apache Tomcat is the official Reference Implementation (RI) for Java Servlets and JavaServer Pages (JSP). Tomcat is an open-source project, under the "Apache Software Foundation" (which also provides the famous open-source industrial-strength Apache HTTP Server). The mother site for Tomcat is http://tomcat.apache.org.

This configuration guide is NOT meant for production purpose, but merely for teaching and self-learning. This guide is applicable to Tomact 6.0.x. Read "Tomcat 7 - How to Install and Configure" for Tomcat 7.

This guide is applicable to my EE3072 Module P311.

Step 0: Read the Tomcat Documentation

Aaviable at Tomcat mother site (@ http://tomcat.apache.org). Select the documentation ⇒ Tomcat 6.0.

Step 1: Download Tomcat
Step 2: Create Environment Variable
Step 3: Configuring "$CATALINA_HOME\conf\server.xml"

TCP Port Number: The default TCP port number configured in Tomcat is 8080, you may choose any number between 1024 and 65535 to run your Tomcat Test server. We shall stick to port 8080 in this article. (For production server, you should use port 80, which is pre-assigned to HTTP as the default port.)

<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

Context: A web context is simply a web application running under Tomcat Server. To create a new web applicaiton, add your application's "path" (URL path used by users to access your application) and provide the "docBase" (directory where you store your application codes), before the </Host> end-tag, as follows:

        ......
        ......
        <Context path="/ws" docBase="d:/workshop" reloadable="true">
        </Context>
      </Host>
    </Engine>
  </Service>
</Server>

Explanation:

In your application's context root "d:\workshop":

Note: This configuration is meant for my laboratory class, where each student is given a dedicated directory in another drive. For production, it is recommended that you store your application under "$CATALINA_HOME/webapps". In this case, you do not have to write the <Context> explicitly. A context will be automatically generated based on your application's directory name. For example, if your directory is called "eshop", a context called "eshop" will be created automatically.

[Click HERE (right-click and "Saved Link As") to download the "server.xml" configuration file.]

Step 4: Configuring "conf\web.xml" and "conf\context.xml" for "Invoker Servlet"

WARNING: The so-called "Invoker Servlet" that we are going to use is an evil (see Tomcat's FAQ @ http://wiki.apache.org/tomcat/FAQ/Miscellaneous on why is it evil), and should not be used for production purpose. But it is really a quick and dirty way for my teaching classes, and I shall continue to use it for teaching.

"$CATALINA_HOME\conf\web.xml": Enable the Directory Listing

<servlet>
  <servlet-name>default</servlet-name>
  <servlet-class>
    org.apache.catalina.servlets.DefaultServlet
  </servlet-class>
  <init-param>
    <param-name>debug</param-name>
    <param-value>0</param-value>
  </init-param>
  <init-param>
    <param-name>listings</param-name>
    <param-value>true</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
 
← The default servlet name
 
← The default servlet class
 
 
 
 
 
 
← Directory Listing
← Change from "false" to "true" to enable directory listing
 
 
 

Note: If the listing is enabled, Tomcat will display the directory listing when user issues an URL to a directory. Otherwise, Tomcat returns an error "404 Page Not Found". Again, enabling directory listing is handy in testing, but poses security risk in production.

"$CATALINA_HOME\conf\web.xml": Enable "Invoker Servlet" and Specify its URL Mapping

<!--
  <servlet>
  <servlet-name>invoker</servlet-name>
  <servlet-class>org.apache.catalina.servlets.InvokerServlet
  </servlet-class>
  <init-param>
  <param-name>debug</param-name>
  <param-value>0</param-value>
  </init-param>
  <load-on-startup>2</load-on-startup>
  </servlet>
-->
   
......
   
<!-- The mapping for the invoker servlet -->
<!--
  <servlet-mapping>
  <servlet-name>invoker</servlet-name>
  <url-pattern>/servlet/*</url-pattern>
  </servlet-mapping>
-->
← Remove this line (comment begin)
 
 
 
 
 
 
 
 
 
 
← Remove this line (comment end)
 
 
 
 
← Remove this line (comment begin)
 
 
 
 
← Remove this line (comment end)

"$CATALINA_HOME\conf\context.xml": Enable privilege for "Invoker Servlet"
We need to grant privilege (evil!!!) to the "Invoker Servlet" by changing the <Context> begin-tag in "conf\context.xml":

<Context privileged="true" reloadable="true">
  ......
  ......
</Context>

Note: In this configuration, we actually grant privilege to all the applications system-wide, which is really a big evil!

[Click HERE (right-click and "Saved Link As") to download the "web.xml" configuration file.]

[Click HERE (right-click and "Saved Link As") to download the "context.xml" configuration file.]

So what is this evil Invoker Servlet?

In a nut shell, it is a dirty way of deploying servlets in mass. The proper way to deploy servlets is to configure each and every servlet in the application's configuration file. This is tedious (and problematic in my teaching classes).

Suppose that we have a context "ws" with document base of "d:\workshop", and we have created a servlet called "TestServlet.class". With the Invoker Servlet enabled, we could simply drop our servlet into the application's "WEB-INF\classes" (i.e., "d:\workshop\WEB-INF\classes\TestServlet.class"). Users can request this servlet via URL http://hostname:8080/ws/servlet/TestServlet. In other words,, the URL path "servlet" is mapped to "WEB-INF\classes".

Step 5: Start the Tomcat Server

You can start the Tomcat Server by running "$CATALINA_HOME\bin\startup.bat". A new console window will be started (as shown below). Study the messages (especially the Tomcat's port number). Future error messages will be send to this console window. System.out.println() issued by our servlets will also be sent to this console.

... change directory to $CATALINA_HOME\bin ...
> startup
......
......
Oct 20, 2009 10:56:37 PM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
......
Oct 20, 2009 10:56:46 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 9215 ms

Start a browser and issue URL "http://localhost:8080" to access the Tomcat home page (as shown), and URL "http://localhost:8080/ws" to access your web application "/ws". localhost (with IP address of 127.0.0.1) is meant for local loop-back testing only. For users on the other machines over the Internet, they have to use the proper IP address or DNS hostname to access the server.

You can shutdown the server by running "$CATALINA_HOME\bin\shutdown.bat". If Tomcat does not respond to the shutdown command, you could terminate Tomcat by pressing Ctrl-Break (or Ctrl-C) on the Tomcat's console window. But do not kill the cat by pressing the "close" button.

Step 6: Java Servlet JAR file

Servlet API is needed to compile Java servlet. Servlet API is not part of JDK (but belongs to Java EE). Tomcat also included a copy of Servlet API. For simplicity, you could COPY the Servlet jar-file "$CATALINA_HOME\lib\servlet-api.jar" into your JDK's extension directory "$JAVA_HOME\jre\lib\ext" (where $JAVA_HOME is the JDK installed directory).

Alternatively, you could include the Servlet jar- file in the CLASSPATH.

Step 7: Write and Deploy a Test Java Servlet

Write the following servlet called "EchoServlet.java" and save it under your application's "WEB-INF\classes" (i.e., "d:\workshop\WEB-INF\classes\EchoServlet.java". Compile the source into "EchoServlet.class".

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
   
public class EchoServlet extends HttpServlet {
   public void doGet(HttpServletRequest request,
         HttpServletResponse response)
         throws IOException, ServletException {

      response.setContentType("text/html");
      PrintWriter out = response.getWriter();

      out.println("<html>");
      out.println("<head><title>Servlet Test</title></head>");
      out.println("<body>");
      out.println("<p>Hello,</p>");
      out.println("<p>Request URI: " + request.getRequestURI() + "</p>");
      out.println("<p>Protocol: " + request.getProtocol() + "</p>");
      out.println("<p>PathInfo: " + request.getPathInfo() + "</p>");
      out.println("<p>Remote Address: " + request.getRemoteAddr() + "</p>");
      out.println("</body>");
      out.println("</html>");
   }
}

To invoke this servlet, issue URL http://localhost:8080/ws/servlet/EchoServlet.

If Things Go Wrong...

Deploying Web Applications in Tomcat

This is the proper way of deploying web application (without using the evil Invoker Servlet):

Create a new Context (web application): Either

Create the directory structure for the new context:

Write your Application's Web Configuration File called "web.xml" and place it under your application's "WEB-INF" directory.

The complete specification for "web.xml" can be found in the "Java Servlet Specification" (@ http://java.sun.com/products/servlet), under "Deployment Descriptor".

Suppose that you wish to deploy two servlets: TestServlet.class and QueryServlet.class (that have to be kept under your application's "WEB-INF\classes" directory):

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app 
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
    "http://java.sun.com/dtd/web-app_2_3.dtd">
   
<web-app>
  <servlet>
    <servlet-name>Test</servlet-name>
    <servlet-class>TestServlet</servlet-class>
  </servlet>
   
  <servlet>
    <servlet-name>Query</servlet-name>
    <servlet-class>QueryServlet</servlet-class>
  </servlet>
   
  <servlet-mapping>
    <servlet-name>Test</servlet-name>
    <url-pattern>/Echo</url-pattern>
  </servlet-mapping>
   
  <servlet-mapping>
    <servlet-name>Query</servlet-name>
    <url-pattern>/Query</url-pattern>
  </servlet-mapping>
   
  <session-config>
    <session-timeout>30</session-timeout>    <!-- 30 minutes -->
  </session-config>
</web-app>

Explanation:

Changing the default "webapps" directory

The default directory for deploying web applications is $CATALINA_HOME\webapps. You could change the default by modifying the configuration file "conf\server.xml" <host> tag's "appBase" attribute as follows:

<Host name="localhost"  appBase="webapps"
      unpackWARs="true" autoDeploy="true"
      xmlValidation="false" xmlNamespaceAware="false">
   ......
</host>

Directory Listing

Enable directory listing is handy for test server but not desire for production server. To enable directory listing for all the web applications, modify the $CATALINA_HOME\conf\web.xml, by changing the "listings" to "true", as follows:

<!-- The default servlet for all web applications, that serves static     -->
<!-- resources.  It processes all requests that are not mapped to other   -->
<!-- servlets with servlet mappings.                                      -->

<servlet>
  <servlet-name>default</servlet-name>
  <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
  <init-param>
    <param-name>debug</param-name>
    <param-value>0</param-value>
  </init-param>
  <init-param>
    <param-name>listings</param-name>
    <param-value>true</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
    
<!-- The mapping for the default servlet -->
<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

Explanation: When a user reference the URL-path "/" (i.e., http://host:port/context-path/), the DefaultServlet will be invoked to show the directory listing.

If you wish to allow directory listing of this web application only, you could disable the directory listing in "$CATALINA_HOME\conf\web.xml" globally, and define the following <servlet> and <servlet-mapping> in your application's "WEB-INF\web.xml", as follows. You need to use another servlet-name for the DefaultServlet.

<servlet>
  <servlet-name>DirectoryListing</servlet-name>
  <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
  <init-param>
    <param-name>debug</param-name>
    <param-value>0</param-value>
  </init-param>
  <init-param>
    <param-name>listings</param-name>
    <param-value>true</param-value>
  </init-param>
</servlet>
   
<servlet-mapping>
  <servlet-name>DirectoryListing</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

Deploying a Web Application in a WAR file

You could use the JDK's jar utiltiy to "zip" up all the files of a web application to produce a so-called WAR (Web Application Archive) file for deployment, or distribution.

.... Change current directory to the web application's context root
> jar cvf test.war .

Drop the test.war into $CATALINA_HOME\webapps. A context called test will be created automatically. You can access the web application via URL http://host:port/test.

(Tomcat actually unpacks the test.war into a test directory in $CATALINA_HOME\webapps.)

Automatic Servlet Reload

To enable automatic servlet reload, you need to specify <Context reloadable="true">...</Context> (either in "$CATALINA_HOME\conf\context.xml" or "$CATALINA_HOME\conf\server.xml").

The following messages appear on the Tomcat's console if you re-compile your servlet:

XXX X, XXXX XX:XX:XX XX org.apache.catalina.core.StandardContext reload
INFO: Reloading this Context has started

Tomcat's Startup Script

To start tomcat server, you could invoke the batch file "startup.bat" (in directory "$CATALINA_HOME\bin", where CATALINA_HOME refers to the Tomcat installed directory). The "startup.bat" invokes "catalina.bat start".

Alternatively, you could call the "catalina.bat" directly, which provides more options of starting Tomcat. Enter "catalina" to view the options:

> catalina
Using CATALINA_BASE:   D:\bin\tomcat6.0.16
Using CATALINA_HOME:   D:\bin\tomcat6.0.16
Using CATALINA_TMPDIR: D:\bin\tomcat6.0.16\temp
Using JRE_HOME:        d:\bin\jdk1.6
Usage:  catalina ( commands ... )
commands:
  debug             Start Catalina in a debugger
  debug -security   Debug Catalina with a security manager
  jpda start        Start Catalina under JPDA debugger
  run               Start Catalina in the current window
  run -security     Start in the current window with security manager
  start             Start Catalina in a separate window
  start -security   Start in a separate window with security manager
  stop              Stop Catalina
  version           What version of tomcat are you running?

Study the source codes of "Tomcat.bat" and "catalina.bat", if interested. Read "Command Shell - How to" about the syntax of batch files. At times, I need to use these files (comment-out the "ECHO OFF") to debug Tomcat's startup problems.

Running Tomcat as a Windows Service

In a production environment, it is more convenient to run Tomcat as a "service", so that it can start automatically whenever the system is started (or re-start automatically after an unexpected interruption).

To install Tomcat as a service, start a CMD shell (with administrator right) and run:

... Change directory to $CATALINA_HOME\bin ...
$CATALINA_HOME\bin> service install
Installing the service 'Tomcat6' ...
Using CATALINA_HOME:    d:\tomcat-6.0.20
Using CATALINA_BASE:    d:\tomcat-6.0.20
Using JAVA_HOME:        d:\jdk1.6
Using JVM:              d:\jdk1.6\jre\bin\server\jvm.dll
The service 'Tomcat6' has been installed.

The Tomcat service called "Apache Tomcat 6" is installed and will start automatically whenever the system is started. Check the "Services" under "Control Panel" ⇒ "Administrative Tools".

A GUI application called Tomcat6w is available for monitoring and configuring Tomcat services. Read "Windows service HOW-TO" under the Tomcat documentation ($CATALINA_HOME\webapps\docs\windows-service-howto.html). Try running the Tomcat6w.

$CATALINA_HOME\bin> tomcat6w

You could put the Tomcat icon in the system tray via the MS (Monitor Service) option:

$CATALINA_HOME\bin> tomcat6w //MS//

You can start/stop the Tomcat service now via (a) Tomcat6w; (b) "Control Panel" ⇒ "Administrator Tools" ⇒ "Services" ⇒ "Apache Tomcat 6" ⇒ "Start"; or (c) issue the following command from a CMD shell:

> net start tomcat6
The Apache Tomcat 6 service is starting..
The Apache Tomcat 6 service was started successfully.
......
......
> net stop tomcat6
The Apache Tomcat 6 service is stopping..
The Apache Tomcat 6 service was stopped successfully.

To uninstall Tomcat Service, use Tomcat6w or issue the following command:

$CATALINA_HOME\bin> service remove
The service 'Tomcat6' has been removed

A flip side of running Tomcat as a service is you need to read the error messages from $CATALINA_HOME\logs instead of the Tomcat console.

 

REFERENCES & RESOURCES

Latest version tested: Tomcat 6.0.29
Last modified: August 30, 2010