Hangin’ with Tomcat

Tired of serving up static Web pages with plain old vanilla Apache? Try adding a dynamic spike of Java to the mix with Tomcat.


For years, system administrators have been frustrated with installing client/ server applications on the desktop. The difficulty of managing a user’s desktop can seem insurmountable; they never seem to want to do things your way. While there are tools and systems available to help you manage the complexity of the task, the tools themselves are expensive and complicated. However, there has been a light on the horizon for some time now, and that light has a name: Web applications.

In many ways, a Web application is the ultimate client/ server solution; everyone has a Web browser on his or her desktop, and everyone has a Web server. The user simply fires up their browser, points it at your server, and voila — instant client/server application. The user doesn’t have to download anything other than the Web browser; the administrator’s biggest worry is making sure the Web server keeps running. In reality, we all know that it hasn’t been that easy. Keeping up with new versions of Web browsers and servers has proven to be a headache, and making your application work with both Netscape and Internet Explorer can be a real challenge.

Things May Change

This article is being written before the Java Servlet 2.3 and Java Server Pages 1.2 specifications have been finalized and Tomcat 4.0 has officially been released. As of this writing, the specifications are due to be finalized in October, with the final version of Tomcat 4.0 soon to follow. While the developers of Tomcat always strive for consistency and stability, they will make changes if they feel it is necessary. In particular, the Apache connector mod_webapp (see “Getting Apache and Tomcat to Play Nice”) is currently experiencing a great deal of change and may not work exactly as described.

For years, Web applications have been developed using CGI scripts to create dynamic content. However, CGI applications have a number of limitations. Traditional CGI applications are reloaded for every request, and if there are 50 requests, there are 50 copies of your application in memory. A number of server vendors attempted to get around this limitation by developing APIs that let you build applications that hook straight into the server and are loaded into memory only once. This lets you create very fast Web applications. However, the biggest problem with these proprietary solutions is that most of them aren’t portable. You can’t take your favorite Web application and simply drop it into a new server; more often than not, significant portions of it have to be rewritten to use the different API.

Java servlets attempt to solve many of these problems. A servlet is, in essence, a Java class that provides you with information about a request from a user and lets you return a dynamic response. The servlet specification is designed so that any protocol can use this request-response model, but it really has only caught on with HTTP. Since the servlet is written in Java, you have access to all the power built into the Java language.

A servlet container is an application that hosts servlets, providing the communication path between the Web server and your servlet. The container ensures there is a single instance of your servlet in memory and starts a new thread that executes your servlet’s methods for each request. The servlet container reference implementation is named Tomcat and was originally donated to the Apache Software Foundation (ASF) by Sun.

Once people started using servlets, they rediscovered one of the big problems of creating dynamic content that has been around since CGIs were first introduced. Creating HTML using a series of println() statements is painful, problematic, and difficult to maintain. In addition, Web page designers aren’t Java developers; they shouldn’t be expected to create a page and then count on a developer to correctly implement it. What happens when the designer wants to change the look and feel of the page? The maintenance nightmare of this situation spurred the rapid development of the Java Server Pages (JSP) specification.

In essence, a JSP is a combination of static HTML and Java code that creates the dynamic content. At runtime, the JSP page is transformed into a servlet by the servlet container, such that the static HTML in the page is written out unchanged, and the Java code embedded in the page is executed in the right place to generate the dynamic content. If you’ve used PHP before, you’ll find several similarities with JSP. Both use a mix of static HTML and code that the server must execute.

While this code/content mix is great for most developers, page designers end up needing to write Java code directly into their HTML page. This can be very complicated for the average Web page designer. There are a couple of ways to keep designers from needing to learn Java. Using Java Beans is one solution. A Java Bean is simply a Java class that conforms to a standard way of getting and setting properties. A Java developer will create Java Beans to encapsulate business rules and information that the HTML designer can use to create the dynamic content without having to learn all the intricacies of the Java language. The complex business rules are subsumed in the object, which then provides the data through its properties in an easy to understand format. Of course, the JSP specification has support for the creation and use of Java Beans within a page.

Servlets and JSPs: The Best of Both Worlds

JSPs seem to provide the ultimate solution to the Web application problem. You can create HTML pages with your favorite editor; simple tagging can add dynamic content with all of the power of Java behind it. Unfortunately, the assumption behind a JSP is that it provides a single, top-down page view of your application. This is often not adequate for making complex decisions based on user input and business data. However, servlets are good at those complex decision-making actions. Using servlets as the controller and JSPs as the presentation layer of your application is a form of the Model View Controller architecture, otherwise known as Model 2. The Struts project on Jakarta (http://jakarta.apache.org/struts/) is a formalized framework implementing Model 2 with servlets and JSPs.

The other way to solve the Java code problem is to use custom tag libraries. This allows Java developers to create tags for use by JSP page writers. These tags can move much of the scripting logic out of the page, keeping it easier to understand for most HTML authors.

This articles does not address tag libraries or how to create Java Beans.

Tomcat 4.0 is the reference implementation of the Java Servlet 2.3 and Java Server Pages 1.2 specifications. After reading this article, you will know how to install Tomcat, write and install a simple Web application, and configure Tomcat to work with the Apache Web server. You should have a Java 2 Platform, Standard Edition (J2SE) conforming JDK, and the Apache Web server installed on your system and should be comfortable configuring Apache.

Getting and Installing Tomcat

Tomcat is part of the Jakarta Project (http://jakarta.apache.org), which is dedicated to providing commercial-quality server solutions based on the Java platform. You need to download the latest released version of Tomcat, which is available from http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/. At the time of this writing, Tomcat 4.0 is in beta 5, so there is no RPM available. However, the tarball version is always available. You should download the tarball into your home directory to keep things simple.

Extract the tarball into your directory of choice, and you have successfully installed Tomcat. Typically, if you are installing Tomcat on a server machine and intend to integrate it with Apache, you will probably want to install it in roughly the same location as the Web server. For example, Apache is often installed into /usr/local/apache, so you may want to extract the tarball into /usr/local with the following commands:

cd /usr/local
su -c ‘gunzip -c ~/jakarta-tomcat-4.0-b5.tar.gz | tar -xvf -’

You will need to provide the root password when prompted. If you don’t have root access, you can install Tomcat wherever you like (usually in your home directory). Keep in mind, however, that you will likely be able to run Tomcat in stand-alone mode only and will not be able to integrate it with Apache.

Running Tomcat for the First Time

Typically, the first time you run Tomcat you aren’t installing any new Web applications or doing anything unusual; you really should get Tomcat running straight out of the box before attempting anything else. Before we can get Tomcat operational, we need to do a little bit of setup. You need to set the JAVA_HOME environment variable to point to the root directory of your Java installation. You can optionally set CATALINA_HOME to point to the directory into which you installed Tomcat, and CATALINA_OPTS to provide additional arguments to the Java runtime environment. You’d probably expect the environment variables to be called TOMCAT_HOME and TOMCAT_ OPTS, and they are in the 3.x versions of Tomcat. However, Catalina is the codename of the Tomcat 4.0 servlet container. In order for a system to run both Tomcat 3.x and 4.0, different environment variable names are required; the logical choice is to use the codename for the new container as the variable prefix.

Using CATALINA_OPTS is useful when you have conflicting jars installed in your Java runtime environment extension directory. Jar files in the extension directory have their classes loaded before anything in your classpath, which can create conflicts. The simple solution is to remove the conflicting jar from the extension directory ${JAVA_HOME}/ jre/lib/ext. However, in a corporate environment you may not have the ability to change your Java installation. If there is a jar that contains an earlier version of the servlet classes (javax.servlet.* and javax.servlet. http.*) such as jsdk.jar from the Java Servlet Development Kit 2.1, then you will have trouble running the latest version of Tomcat. A more likely scenario is that an older version of Java API for XML Parsing (JAXP) is interfering with the version provided with Tomcat. In either case, if you don’t need anything in the extensions directory, you can bypass the issue entirely with the following command:

export CATALINA_OPTS=”-Djava.ext.dirs=/some_dummy_dir”

This way, when you run Tomcat, the startup scripts will effectively redirect where the Java runtime will be looking for extension jars.

Table One: Tomcat Environment Variables

Environment VariableValue
JAVA_HOMEYour Java installation directory
CATALINA_HOMEThe Tomcat installation directory
CATALINA_OPTSCommand line switches to pass to the Java Runtime Environment

To recap, Table One outlines what environment variables you need to run Tomcat. Once your environment is configured correctly, starting Tomcat is a snap:


If everything goes well, you should see the following:


Using CATALINA_HOME: /usr/local/jakarta-tomcat-4.0-b5

Point your favorite browser to http://localhost:8080/, and you should see a page telling you that you have successfully installed Tomcat. If you either don’t see anything, or your browser reports an error, or you get redirected to a search engine, then Tomcat was unable to start for some reason. It’s time to start combing through the logs in CATALINA_ HOME/logs, particularly catalina.out and catalina_ log.{current_date}.txt, where current_date is today’s date.

Now would be a good time to play with the example servlets and JSPs and to browse the documentation that is included with Tomcat. You should try to get all of the examples working; you will get a good feel for what Tomcat can do. If you encounter any problems while running some of the examples, it’s probably due to errors in your setup. Make sure that there are no extraneous jars in your classpath or your extension directory (typically $JAVA_HOME/ jre/lib/ext).

Creating and Deploying Your Own Web Application

Now that we have Tomcat up and running, it’s time to create and deploy your own sample Web application. To make things interesting, the application will use a combination of servlets, JSPs, and static content. The premise for the application is simple, and admittedly not very useful; it’s intended to demonstrate what you can do with servlets and JSPs and not much more.

The sample application asks you what city you want to travel to in a standard HTML form. The form passes your choice onto a control servlet that looks at the city name and decides which JSP to show. If you have entered the correct city, then you win. The important thing to note about the application is that servlets, regular HTML, and JSPs can all interact in the same Web application without any significant problems.

Download the Web Archive (WAR) file that contains the Web application from http://www.linux-mag.com/downloads/wide_world.war into your home directory. You will need to perform the following action:

cp ~/wide_world.war webapps

To see the application in action, point your browser at http://localhost:8080/wide_world/ and enter the name of any city. See how many times it takes before you guess where you should go.

Getting Apache and Tomcat to Play Nice

If you have a lot of static content mixed in with your Web applications on a large site, you are far better off having Apache serve the static content and letting Tomcat deal solely with the dynamic content. To do this effectively, you need to connect Apache and Tomcat so that requests to your Web server are transparently passed to Tomcat when necessary. With Apache 1.3 and Tomcat 4.0, that connector is mod_webapp. As I’m writing this article, mod_webapp is still fairly experimental, and there isn’t an Apache 2.0 version. However, since it’s the easiest connector to configure, and Apache 2.0 support is a must, it’s probably a good place to start.

In the current beta, you need to compile mod_webapp yourself. The compilation instructions are found in $CATALINA_HOME/src/connectors/docs/apache-1.3.html, as are the instructions for installing and configuring mod_webapp. In the final release, you should be able to obtain a pre-compiled mod_ webapp.so fairly easily. In either case, once you have obtained your mod_ webapp.so, copy it into your Apache modules directory (typically /usr/ local/apache/libexec if you’ve built and installed Apache yourself). Next, add the following two lines to your httpd.conf file:

LoadModule webapp_module [your modules directory]/mod_webapp.so
AddModule mod_webapp.c

The next step is configuring your connection between Apache and Tomcat with the directives in mod_webapp.

Creating a Connection

The WebAppConnection directive is used to create a connection between the Web server and the servlet container with the following parameters:

WebAppConnection [connection name] [connection provider] [provider parameters]

The connection name is the unique name for the connection between the server and the container. The connection provider is effectively the protocol that is to be used for communication between the Web server and the servlet container. The provider parameters is an optional provider-specific set of parameters that are used to configure the connection.

Typically, you will always use the WebAppConnection directive to connect to Tomcat with the WARP protocol on your local machine on port 8008. WARP is the communication protocol developed by the Tomcat developers to provide a vendor-neutral way of communicating with a Web server. The default Tomcat installation creates the servlet container side of the WARP connection and configures it to listen on port 8008. So, your connection directive should look like:

WebAppConnection warpConnection warp localhost:8008

Tomcat Figure One
Figure One: Apache and Tomcat communication using WARP and mod_webapp.

Once you have a connection, you will need to tell mod_ webapp exactly which Tomcat applications you want to be made available through the Web browser. Take a look at Figure One for an illustration of how all of the pieces fit together.

Mounting a Web Application

The WebAppMount directive provides the necessary mapping for mounting the Web application to a specified URL path with the following parameters:


The application name is the Web application name within the servlet container. Typically, this is the name of the WAR file without the .war extension. The connection name parameter specifies which connection to use. The connectionname must already be declared with the WebAppConnection directive. The URL path specifies what URL path the application should be mounted under. To mount our wide_world application, your mount directive should look like:

WebAppMount[application name][connection name][URL path]

Connecting to Your Web Application

Before we can connect to our Web application through Apache, we will need to restart Apache in order to have the mod_webapp directives take effect. Once Apache has restarted, simply point your browser to http://localhost/wide_world/ and you should see the same application we deployed in the “Creating and Deploying Your Own Web Application” section above.

Just Dive In

After that whirlwind tour of servlets, JSPs, Tomcat, and Apache, you should be ready to dive into the world of Java Web application development. Spend a while exploring Tomcat and all the sample applications. After that, dig into the Resources to keep learning how to implement and deploy your Web applications in a world-class servlet container.


http://jakarta.apache.org/tomcat The main Tomcat Web site

http://java.sun.com/products/servlet The main Servlet Web site

http://java.sun.com/products/jsp The main Java Server Pages Web site

http://jakarta.apache.org/struts The Struts Framework Web site

http://www.linux-mag.com/downloads/wide_world.war The sample code used in this article

Glenn McAllister is a part-time committer on the Jakarta Ant project. He can be reached at glenn@somanetworks.com

Comments are closed.