BUY THIS BOOK
Add to Cart

PDF $27.99

Safari Books Online

What is this?

Looking to Reprint or License this content?

Tomcat: The Definitive Guide
Tomcat: The Definitive Guide

By Jason Brittain, Ian F. Darwin

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Getting Started with Tomcat
The first Java servlet container was Sun Microsystems's Java Web Server (JWS). It was more affordable than most commercial server offerings, but it did not enjoy widespread commercial success. This was due largely to Java's novelty and the fact that servlets had only recently been introduced. One of JWS's main outgrowths, however, was the Java Servlet Specification, a de facto standard that Sun documented and made available separately. One big success of JWS was that it put Java servlets in the limelight.
In 1996, a plethora of free Java servlet containers became popular. Apache's JServ and CERN/W3C's Jigsaw were two of the earliest open source Java servlet containers. They were quickly followed by several more, including Jetty (http://www.jetty.org), the Locomotive Application Server (see the web archives at http://web.archive.org/web/*/http://www.locomotive.org), Enhydra (http://www.enhydra.org), and many others. At the same time, commercial servlet containers became available as the industry embraced the Java servlet standard; some of these were WebLogic's Tengah, ATG's Dynamo, and LiveSoftware's JRun.
In 1997, Sun released their first version of the Java Servlet Development Kit (JSDK). The JSDK was a very small servlet container that supported JavaServer Pages (JSP) and had a built-in HTTP 1.0 web server. In an effort to provide a reference implementation for developing servlets, Sun made it available as a free download to anyone wanting to experiment with the new Java server-side standard. It also had success as a testing and development platform, in preparation for deployment to a commercial server.
In the first half of 1998, Sun announced their new JSP specification, which built upon the Java Servlet API and allowed more rapid development of dynamic web application content. After the 2.1 release of the JSDK (now called the JSWDK to add "Web" to the name), James Duncan Davidson at Sun rewrote the core of the older JSDK server. At the heart of this new Java servlet engine reference implementation was a brand new servlet container named Tomcat. Its version number started at 3.0 because it replaced JSDK Version 2.1.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Installing Tomcat
There are several paths to getting Tomcat up and running. The quickest way is to download and run the compiled binary. Tomcat is written in Java, which means you must have a modern Java runtime installed before you can build or test it. Read Appendix A to make sure you have Java installed properly.
One of the benefits of open source projects is that programmers find and fix bugs and make improvements to the software. If you're not a programmer, there is little to be gained from recompiling the source, since you are not interested in this level of interaction. To get started quickly, download a binary package for your system.
If you do want some hints on compiling from source, see Chapter 9.
There are two levels of packaging. The Apache Software Foundation publishes binary packages in the form of releases and nightly builds. Other organizations repackage these into RPMs for Linux, packages for BSD, and so forth. The best way to install Tomcat, then, depends on your system. We'll explain this process on several systems: Linux, Solaris, Windows, Mac OS X, and OpenBSD.
Regardless of your platform, if you choose the Apache Jakarta Tomcat binary release, there are two editions to choose from. Here's how the Jakarta binary release download page describes each:
Standard
This is a full binary distribution of Tomcat 4, which includes all optional libraries and an XML parser (Xerces 2.0.1), and can be run on JDK 1.2+.
JDK 1.4 LE
This is a lightweight binary distribution of Tomcat 4, designed for JDK 1.4. It does not include any of the optional binaries or the necessary XML parser (as these are included in JDK 1.4). All the components of this distribution are open source software.
LE-style releases do not contain JavaMail, Java Activation Framework, Xerces, Java Naming and Directory Interface (JNDI), or the JDBC Standard Extension.
Tomcat is available in two different binary release formats for Linux users:
Multiplatform binary releases
You can download, install, and run any of the Tomcat binary releases from Apache's Jakarta web site, regardless of the Linux distribution you run. This allows you to install Tomcat into any directory you choose, and you can install it as any user ID in the system. However, because the installation is not tracked by any package manager, it will be more difficult to upgrade or uninstall later.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Starting, Stopping, and Restarting Tomcat
Once you have the installation completed, you will probably be anxious to start Tomcat and see if it works. This section details how to start up and shut down Tomcat, including specific information on each supported operating system. It also details common errors that you may encounter, enabling you to quickly identify and resolve any problems you run into.
There are several scripts in the bin subdirectory that you will use for starting and stopping Tomcat. All the scripts you will need to invoke directly are provided both as shell script files for Unix (.sh) and batch files for Windows (.bat). Table 1-1 lists these scripts and describes each. When referring to these scripts, we have omitted the filename extension because catalina.bat has the same meaning for MS-Windows users as catalina.sh has for Unix users. Therefore, the name in the table appears simply as catalina. You can infer the appropriate file extension for your system.
Table 1-1: Tomcat invocation scripts
Script
Purpose
catalina
The main Tomcat script, which runs the java command to invoke the Tomcat startup and shutdown classes.
cpappend
Used internally, and then only on Windows systems, to append items to Tomcat classpath environment variables.
digest
Makes a crypto digest of Tomcat passwords. Use it to generate encrypted passwords.
jasper
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Automatic Startup
Once you have Tomcat installed and running, you can set it to start automatically when your system reboots. This will ensure that every time your system comes up, Tomcat will be running and handling requests. Unix users will make changes to their init scripts, and Windows users will need to set Tomcat up as a service. Both approaches are outlined in this section.
If you've installed Tomcat via the RPM, getting it to run on a reboot is simply a matter of telling your system to run the tomcat4 service when it enters the multiuser run level.
If you know how to use chkconfig, as the root user you can simply chkconfig tomcat4 for the run levels of your choice.
You can use either tksysv or ntsysv to set Tomcat up to start on reboot. tksysv offers a graphical user interface for turning services on and off, and ntsysv offers a text user interface to do the same. Try running tksysv as detailed in the following steps:
  1. Enter tksysv at your command prompt. See Figure 1-8 for a screenshot of tksysv.
    # tksysv &
    Figure 1-8: Adding the tomcat4 service in tksysv on Linux
  2. Choose "tomcat4" from the list of available services on the left.
  3. Click the Add button.
  4. Check the "Start tomcat4" checkbox at the top.
  5. Check the "run level 3" checkbox (or whichever run level you wish it to run in; see /etc/inittab for more information about your server computer's run levels).
  6. Click the Done button.
  7. A new dialog window will pop up; just click the Add button.
  8. Close the tksysv window.
  9. Reboot and see if Tomcat starts up when the system comes back up.
If tksysv isn't available but ntsysv is, do the following:
  1. Run ntsysv. See Figure 1-9 for a screenshot of ntsysv.
    # ntsysv
    Figure 1-9: Adding the tomcat4 service in ntsysv on Linux
  2. Scroll down to the tomcat4 service.
    If you don't see the tomcat4 service, you probably didn't install Tomcat as a Linux RPM. This procedure works for RPM-based installations only.
  3. Press the spacebar to check the checkbox in front of the tomcat4 listing (an asterisk will appear between the brackets to signify that it is selected).
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Testing Your Tomcat Installation
Once you have Tomcat installed and started, you should confirm that it has successfully started up. Open the URL http://localhost:8080 in a browser and verify that you see output like that shown in Figure 1-12.
Figure 1-12: Success!
If you have changed the port number in server.xml, you will need to use that same port here.
Now that Tomcat is up and running, you can begin to customize its behavior. This is discussed in Chapter 2.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Configuring Tomcat
Once Tomcat is up and running, you will want to keep an eye on it to help it along occasionally. Troubleshooting application servers can be intimidating. In this chapter, we show you the various places to look for information about your server, how to find out why things aren't working, and give some examples of common mistakes in setting up and configuring Tomcat. We round out this chapter with some ideas on performance tuning the underlying Java runtime environment and the Tomcat server itself. Finally, we discuss the Tomcat administration web application, a tool for helping you with the task of keeping Tomcat running.
You can use Tomcat as a standalone web server and servlet container, or you can use it as an add-on servlet container for a separate web server. Both are common, and each is appropriate in certain situations.
The Tomcat authors have spent quite a bit of time and effort to make Tomcat run efficiently as a standalone web server; as a result, it is easy to set up and run a web site without worrying about connecting Tomcat to a third-party web server. Tomcat's built-in web server is a highly efficient HTTP 1.1 server that is quite fast at serving static content once it is configured correctly for the computer on which it runs. They've also added features to Tomcat that one would expect from full-featured web servers, such as Common Gateway Interface (CGI) scripting, a Server-Side Includes (SSI) dynamic page interpreter, a home directory mapper, and more.
The Tomcat authors also realized that many companies and other organizations already run the Apache httpd web server and might not want to switch from that server to Tomcat's built-in web server. The Apache web server is the number one web server on the Internet, and it is arguably the most flexible, fully featured, and supported web server ever written. Even if someone running Apache httpd wanted to switch web servers, it might be difficult for them to do so because their web sites are often already too integrated with Apache's features. Also, it's difficult for other web servers to keep up with Apache efficiency, since it's been tuned for performance in so many different ways over the years.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using the Apache Web Server
You can use Tomcat as a standalone web server and servlet container, or you can use it as an add-on servlet container for a separate web server. Both are common, and each is appropriate in certain situations.
The Tomcat authors have spent quite a bit of time and effort to make Tomcat run efficiently as a standalone web server; as a result, it is easy to set up and run a web site without worrying about connecting Tomcat to a third-party web server. Tomcat's built-in web server is a highly efficient HTTP 1.1 server that is quite fast at serving static content once it is configured correctly for the computer on which it runs. They've also added features to Tomcat that one would expect from full-featured web servers, such as Common Gateway Interface (CGI) scripting, a Server-Side Includes (SSI) dynamic page interpreter, a home directory mapper, and more.
The Tomcat authors also realized that many companies and other organizations already run the Apache httpd web server and might not want to switch from that server to Tomcat's built-in web server. The Apache web server is the number one web server on the Internet, and it is arguably the most flexible, fully featured, and supported web server ever written. Even if someone running Apache httpd wanted to switch web servers, it might be difficult for them to do so because their web sites are often already too integrated with Apache's features. Also, it's difficult for other web servers to keep up with Apache efficiency, since it's been tuned for performance in so many different ways over the years.
With these issues in mind, if you're still considering using Apache httpd and Tomcat together, refer to Chapter 5 for an in-depth look at how to hook these two programs together.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Managing Realms, Roles, and Users
The security of a web application's resources can be controlled either by the container or by the web application itself. The J2EE specification calls the former container-managed security and the latter application-managed security. Tomcat provides several approaches for handling security through built-in mechanisms, which represents container-managed security. On the other hand, if you have a series of servlets and JSPs with their own login mechanism, this would be considered application-managed security. In both types of security, users and passwords are managed in groupings called realms. This section details setting up Tomcat realms and using the built-in security features of Tomcat to handle user authentication.
The combination of a realm configuration in Tomcat's conf/server.xml file and a <security-constraint> in a web application's WEB-INF/web.xml file defines how user and role information will be stored and how users will be authenticated for the web application. There are many ways of configuring each; feel free to mix and match.
In this and future sections, the term context is used interchangeably with web application. A context is the technical term used within Tomcat for a web application, and it has a corresponding set of XML elements and attributes that define it in Tomcat's server.xml file.
In order to use Tomcat's container-managed security, you must set up a realm. A realm is simply a collection of users, passwords, and roles. Web applications can declare which resources are accessible by which groups of users in their web.xml deployment descriptor. Then, a Tomcat administrator can configure Tomcat to retrieve user, password, and role information using one or more of the realm implementations.
Tomcat contains a pluggable framework for realms and comes with several useful realm implementations: UserDatabaseRealm, JDBCRealm, JNDIRealm, and JAASRealm. Java developers can also create additional realm implementations to interface with their own user and password stores. To specify which realm should be used, insert a
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Controlling Sessions
An HTTP session is a series of interactions between a single browser instance and a web server. The servlet specification defines an HttpSession object that temporarily stores information about a user, including a unique session identifier and references to Java objects that the web application stores as attributes of the session. Typical uses of sessions include shopping carts and sites that require users to sign in. Usually, sessions are set to time out after a configurable period of user inactivity. Once a session has timed out, it is said to be an invalid session; if the user makes a new HTTP request to the site, a new, valid session must be created, usually through a relogin.
Tomcat 4 has pluggable session Managers that control the logic of how sessions are handled, and it has session Stores to save and load sessions. Not every Manager uses a Store to persist sessions; it is an implementation option to use the Store interface to provide pluggable session store capabilities. Robust session Managers will implement some kind of persistent storage for their sessions, regardless of whether they use the Store interface. Specifying a Manager implementation works in a similar fashion to specifying a Realm:
<Manager className="some.manager.implementation.className"
         customAttribute1="some custom value"
         customAttribute2="some other custom value"
         <!-- etc. -->
/>
Almost all of the control over sessions is vested in the Manager and Store objects, but some options are set in web.xml (that is, at the context level). These options are described in detail in Chapter 7, under the Section 7.2.6 and Section 7.2.9 element headings.
Session persistence is the saving (persisting) to disk of HTTP sessions when the server is shut down and the corresponding reloading when the server is restarted. Without session persistence, a server restart will result in all active user sessions being lost. To users this means they will be asked to log in again (if you're using container-managed security), and that they may lose the web page they were on, along with any shopping cart information or other web page state information that was stored in the session. Persisting that information helps to ensure that it won't be lost.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Accessing JNDI and JDBC Resources
Many web applications will need access to a relational database. To make web applications portable, the J2EE specification requires a database-independent description in the web applications's WEB-INF/web.xml file. It also allows the container developer to supply a means for providing the database-dependent details; Tomcat developers naturally chose to put this in the server.xml file. Then, the Java Naming and Directory Interface (JNDI) is used to locate database sources and other resources. Each of these resources, when accessed through JNDI, is referred to as a context.
Watch out! A JNDI context is completely different than a Tomcat context (which represents a web application). In fact, the two are completely unrelated.
You probably know whether your web application requires a JDBC DataSource. If you're not sure, look in the web.xml file for the application and search for something like this:
<resource-ref>
  <description>
    The database DataSource for the Acme web application.
  </description>
  <res-ref-name>
    jdbc/JabaDotDB
  </res-ref-name>
  <res-type>
    javax.sql.DataSource
  </res-type>
  <res-auth>
    Container
  </res-auth>
</resource-ref>
As an alternative, if you have the Java source code available, you can look for something like this:
Context ctx = new InitialContext(  );
DataSource ds = (DataSource)
  ctx.lookup("java:comp/env/jdbc/JabaDotDB");

Connection conn = ds.getConnection(  );
... Java code that accesses the database ...
conn.close(  );
If you're not familiar with JNDI usage from Java, a DataSource is an object that can hand out JDBC Connection objects on demand, usually from a pool of preallocated connections.
Tomcat 4 uses the Apache Database Connection Pool (DBCP) by default.
In either of the previous code snippets, the resource string jdbc/JabaDotDB tells you what you need to configure a reference for in the server.xml file. Find the Context element for your web application, and insert Resource and ResourceParam elements similar to those shown in Example 2-12.
Example 2-12. DataSource: Resource and ResourceParam in server.xml
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Servlet Auto-Reloading
By default, Tomcat will automatically reload a servlet when it notices that the servlet's class file has been modified. This is certainly a great convenience when debugging servlets. However, bear in mind that Tomcat must periodically check the modification time on every servlet in order to implement this functionality. This entails a lot of filesystem activity that is unnecessary when the servlets have been debugged and are not changing.
To turn this feature off, you need only set the reloadable attribute in the web application's Context element (in web.xml) and restart Tomcat. Once you've done this, you can still reload the servlet classes in a given Context by using the Manager application (detailed earlier in this chapter).
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Relocating the Web Applications Directory
Depending on how you install and use Tomcat, you may not want to store your web application's files in the Tomcat distribution's directory tree. For example, if you installed Tomcat as a Linux RPM, you probably shouldn't modify Tomcat's files—for instance, conf/server.xml, which you will likely need or want to modify in order to configure Tomcat for your site—because RPM is supposed to have control over the contents of the files it installs. This is likely to be the case with other native package managers as well. Upgrading the Tomcat package means that the native package manager might replace your configuration files with stock versions from the new package. Usually, package managers save the file they're replacing, but even then it's a pain to get your site back in running order. Regardless of how you installed Tomcat, though, it may be a good idea to keep your web site's files clearly separate from the Tomcat distribution files.
Another scenario when you may not want to store your web application files in the Tomcat distribution's directory tree is if you install one copy of the Tomcat distribution, but you wish to run more than one instance of Tomcat on your server computer. There are plenty of reasons why you may want to run more than one Tomcat instance, such as having each one serving content on different TCP ports. In this case, you don't want files from one instance clashing with files from another instance.
In order to have one Tomcat distribution installed while running two or more Tomcat instances of the Tomcat installation, each with different configuration and writeable data directories, you must keep each instance's files separate. During normal usage of Tomcat, the server reads configuration files from the conf and webapps directories, and writes files to the logs, temp, and work directories. This means that for multiple instances to work, each Tomcat instance has to have its own set of these directories, plus its own shared/classes and shared/lib directories. To make this work, just set the CATALINA_BASE environment variable to point to a new directory on disk where the Tomcat instance can find its set of configuration and other writeable directories.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Customized User Directories
Some sites like to allow individual users to publish a directory of web pages on the server. For example, a university department might want to give each student a public area, or an ISP might make some web space available on one of its servers to customers that don't have a virtually hosted web server. In such cases, it is typical to use the tilde character (~) plus the user's name as the virtual path of that user's web site:
http://www.cs.myuniversity.edu/~ian
http://members.mybigisp.com/~ian
The notion of using ~ to mean a user's home directory originated at the University of Berkeley during the development of Berkeley Unix, when the C-shell command interpreter was being developed in the late 1970s. This usage has been expanded in the web world to refer to a particular directory inside a user's home directory or, more generally, a particular user's web directory, typically a directory named public_html.
Tomcat gives you two ways to map this on a per-host basis, using a couple of special Listener elements. The Listener's className attribute should be org.apache.catalina.startup.UserConfig, with the userClass attribute specifying one of several mapping classes. If your system runs Unix, has a standard /etc/passwd file that is readable by the account running Tomcat, and that file specifies users' home directories, use the PasswdUserDatabase mapping class:
<Listener className="org.apache.catalina.startup.UserConfig"
  directoryName="public_html"             
  userClass="org.apache.catalina.startup.PasswdUserDatabase"
/>
Web files would need to be in directories like /home/users/ian/public_html and /users/jbrittain/public_html. Of course, you can change public_html to be whatever subdirectory your users put their personal web pages into.
In fact, the directories don't have to be inside a user's home directory at all. If you don't have a password file but want to map from a user name to a subdirectory of a common parent directory such as /home, use the HomesUserDatabase class:
<Listener className="org.apache.catalina.startup.UserConfig"
   directoryName="public_html"
   homeBase="/home"           
   userClass="org.apache.catalina.startup.HomesUserDatabase"
/>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Tomcat Example Applications
When installed out of the box, Tomcat includes a variety of sample applications, all within the context /examples. These are actually quite useful to people learning how to write JavaServer Pages and servlets. (The two relevant subdirectories under examples are jsp and servlets, each containing several examples, with source code viewable online.) Since these examples are so helpful, you may wish to make them available; on the other hand, you may not want somebody else's examples showing up on your production web server. In that case, you should remove the deployment Context element from the file server.xml in the Tomcat conf directory. Look for the section beginning like this:
<!-- Tomcat Examples Context -->
<Context path="/examples" docBase="examples" debug="0"
         reloadable="true" crossContext="true">
  <!-- Context content -->
</Context>
Comment out all of these lines (and the content in between them), and restart Tomcat. But be careful—it's about 100 lines long, containing examples of many XML deployment elements. And you can't just put the XML comment delimiters <!-- and --> around the element, because comments in XML do not nest! If you don't want to deal with this issue and haven't made any other changes to your server.xml file, you can use the provided server-noexamples.xml. This file is almost identical to the default server.xml, except that it does not contain the examples Context.
Alas, it is maintained by hand, so there are often minor differences between the two files, in addition to the absence of the examples Context.
Just rename the old server.xml to server-examples.xml, and rename server-noexamples.xml to server.xml. Finally, restart Tomcat to put these changes into effect.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Server-Side Includes
Tomcat is primarily meant to be a servlet/JSP engine, but it has a surprising number of abilities that rival those of a traditional web server. One of these is its Server-Side Include (SSI) capability. Traditional web servers provide a means for including common page elements—such as header and footer sections, JavaScript code, and other reusable items—into a web page. This idea is actually patterned on the C-language preprocessor #include mechanism, but it is slightly enhanced for use in web pages. For example, in one of our web sites we have a table navigator that is meant to appear at the left of each page. Instead of copying the table cells into each page, we store them in their own small file. Then, each page that needs the navigator accesses it using code like this:
<!--#include virtual=/"tablenav.html" -->
Files with these directives are generally named with the extension shtml, rather than html, to indicate to the web server that they should be processed differently than standard HTML code.
While JSP experts would argue that it is probably simpler to rename the files to JSP and use a jsp:include element, there might be cases when a large number of legacy pages must be served, and you prefer to keep them as SHTML files, perhaps for compatibility with other servers. It's probably not worthwhile to convert SHTML files to JSP just so you can process them as JSPs. In fact, Tomcat provides an SSI servlet for this very purpose. To enable it, you need only do the following:
  1. Rename the file servlets-ssi.renametojar (found in CATALINA_HOME/server/lib/) to servlets-ssi.jar, so that the servlet processing SSI files will be on Tomcat's CLASSPATH. (This file is normally not installed with the extension jar, which reduces overhead by keeping it out of the CLASSPATH if you're not using it.)
  2. Copy and uncomment the definition of the servlet named ssi from Tomcat's web.xml file to your application's web.xml (this is around line 180 in the distribution). Alternatively, if you want all contexts to have SSI processing, simply uncomment this servlet's definition in Tomcat's global
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Common Gateway Interface (CGI)
As mentioned in the previous section, Tomcat is primarily meant to be a servlet/JSP engine, but it has many capabilities rivalling a traditional web server. One of these is support for the Common Gateway Interface (CGI), which provides a means for running an external program in response to a browser request, typically to process a web-based form. CGI is called common because it can invoke programs in almost any programming or scripting language: Perl, Python, awk, Unix shell scripting, and even Java are all supported options. However, you probably wouldn't run Java applications as a CGI due to the start-up overhead; elimination of this overhead was what led to the original design of the servlet specification. Servlets are almost always more efficient than CGIs because you're not starting up a new operating system-level process every time somebody clicks on a link or button. You can consult a good book on web site management for details on writing CGI scripts.
Tomcat includes an optional CGI servlet that allows you to run legacy CGI scripts; the assumption is that most new backend processing will be done by user-defined servlets and JSPs. A simple CGI is shown in Example 2-13.
Example 2-13. CGI demonstration
#! /usr/local/bin/python
 
# Trivial CGI demo
 
print "content-type: text/html"
print ""
 
print "<html><head>Welcome</head>"
print "<body><h1>Welcome to the output of a CGI under Tomcat</h1>"
print "<p>The subject says all.</p>"
print "</body></html>"
As already mentioned, scripts can be written in almost any language. For the example we chose Python, and the first line is a bit of Unix that tells the system which interpreter to use for the script. On Windows, the filename would have to match some pattern, such as *.py, to produce the same effect. The first few statements print the content type (useful to the browser, of course) and a blank line to separate the HTTP headers from the body. The remaining lines print the HTML content. This is typical of CGI scripts. Of course, most CGI scripts also handle some kind of forms processing, but that is left as an exercise for the reader. Presumably your CGI scripts are already working in whatever language you regularly use for this purpose.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Tomcat Admin Application
Most of the work in this chapter has been figuring out what needs changing in a configuration file; knowing which XML to edit, and then editing that file; and restarting either Tomcat or the affected web application. We end this chapter with a look at an alternative way of making changes to Tomcat, one that will eventually become at least as important as editing XML files (among those who aren't dedicated to hand-editing XML, at any rate).
Most commercial J2EE servers provide a fully functional administrative interface, and many of these are accessible as web applications. The Tomcat Admin application is on its way to become a full-blown Tomcat administration tool rivaling these commercial offerings. First included in Tomcat 4.1, it already provides control over contexts, data sources, and users and groups. You can also control resources such as initialization parameters, as well as users, groups, and roles in a variety of user databases. The list of capabilities will be expanded upon in future releases, but the present implementation has proven itself to be quite useful.
The Admin web application is defined in the auto-deployment CATALINA_BASE/webapps/admin.xml.
If you do not have this file, you may not be running Tomcat 4.1. You will need to upgrade to take advantage of the Admin application.
You must edit this file to ensure that the path specified in the docBase attribute of the Context element is absolute, i.e., the absolute path of CATALINA_HOME/server/webapps/manager. Alternatively, you could just remove the auto-deployment file and specify the Admin context manually in your server.xml file. On machines that will not be managed by this application, you should probably disable it altogether by simply removing CATALINA_BASE/webapps/admin.xml.
You must also have a user who is assigned the admin role. Once you've performed these steps and restarted Tomcat, visit the URL http://<yourhost>/admin or http://<yourhost>:8080/admin, and you should see a login screen. The Admin application is built using container-managed security and the Jakarta Struts framework. Once you have logged in as a user assigned the admin role, you will see a screen like Figure 2-2.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Deploying Servlet and JSP Web Applications in Tomcat
Now that you have Tomcat installed, you will almost invariably need to deploy web applications. This chapter shows you web applications composed of servlets, JSPs, and other files, and then discusses several approaches for deploying them. It ends with a discussion of the Manager web application, which can handle some deployment operations for you.
Before Java servlets, web applications were mostly written in C/C++ or Perl. Usually they were made up mainly of static HTML pages and a few CGI scripts to generate the dynamic content portions of the web application. Those CGI scripts could be written in a platform-independent way, although they didn't need to be (and for that reason often weren't). Also, since CGI was an accepted industry standard across all web server brands and implementations, CGI scripts could be written to be web server implementation-independent. In practice, some are and some aren't. The biggest problem with CGI was that the design made it inherently slow and unscalable.
Another approach to generating dynamic content is web server modules. For instance, the Apache httpd web server allows dynamically loadable modules to run on startup. These modules can answer on preconfigured HTTP request patterns, sending dynamic content to the HTTP client/browser. This high-performance method of generating dynamic web application content has enjoyed some success over the years, but it has its issues as well. Web server modules can be written in a platform-independent way, but there is no web server implementation-independent standard for web server modules—they're specific to the server you write them for, and probably won't work on any other web server implementation.
Java brought platform independence to the server, and Sun wanted to leverage that capability as part of the solution toward a fast and platform-independent web application standard. The other part of this solution was Java servlets. The idea behind servlets was to use Java's simple and powerful multithreading to answer requests without starting new processes. You can now write a servlet-based web application, move it from one servlet container to another or from one computer architecture to another, and run it without any change (in fact, without even recompiling any of its code).
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Layout of a Web Application
Tomcat provides an implementation of both the servlet and JSP specifications. These specifications are in turn part of Sun's Java 2 Enterprise Edition (or, simply, J2EE). J2EE is designed to let application developers move their applications from one compliant application server (a program that implements the J2EE specification) to another, without significant rewriting or revising. In order to accomplish this, applications are packaged in very specific, portable ways; for example, as web application archives or enterprise application archives.
The Java Servlet Specification defines the Web Application Archive (WAR) file format and structure for this very purpose. In order to use implementation-independent web applications, your files must follow certain conventions, such as the directory layout for storing web pages, configuration files, and so on. This general layout is shown in Figure 3-1.
Figure 3-1: Servlet web application file layout
As a concrete example, Acme Widgets' site might look like Example 3-1.
Example 3-1. Example web application file layout
/
/index.jsp
/products.jsp
/widgets/index.html
/widgets/pricing.jsp
/images/logo.png
/WEB-INF/web.xml
/WEB-INF/classes/com/acme/PriceServlet.class
/WEB-INF/classes/DataHelper.class
/WEB-INF/lib/acme-util.jar
As you can see, the web pages (whether static HTML, dynamic JSP, or another dynamic templating language's content) can go in the root of a web application directory or in almost any subdirectory that you like. Images often go in a /images subdirectory, but this is a convention, not a requirement. The WEB-INF directory contains several specific pieces of content. First, the classes directory is where you place Java class files, whether they are servlets or other class files used by a servlet, JSP, or other part of your application's code. Second, the lib directory is where you put Java Archive (JAR) files containing packages of classes. Finally, the web.xml file is known as a deployment descriptor, which contains configuration for the web application, a description of the application, and any additional customization.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Manual Application Deployment
You can set up a web application directory anywhere in your filesystem, but it's a good idea not to situate these directories inside Tomcat's directory—that way, you won't lose them if you remove Tomcat to install a newer version. So, installing a web application by hand consists merely of creating a directory, copying in whatever files are needed, and telling Tomcat about the directory by specifying it as a context. This last step is usually done by the Manager application described later in this chapter or by placing your WAR file in the $CATALINA_BASE/webapps directory.
The server.xml file is a Tomcat-specific file that lists, among many other things, the context for each web application. A context is described by an XML tag of the same name (Context) and is covered in detail in Chapter 7.
You can configure the URI to which a servlet is mapped by providing a servlet-mapping element in the WEB-INF/web.xml file, for example. Listing the servlet in the descriptor is required if you want to provide an alternate mapping, pass any initialization parameters to the servlet, specify loading order on startup, and so on. The servlet element is an XML tag that appears near the start of web.xml, and it is used for all of these tasks.
Chapter 7 details all of the options available to servlets at deployment time.
Here is an example of a servlet with most of its allowed subelements:
<servlet>
  <icon>
    <small-icon>/images/tomcat_tdg16x16.jpg</small-icon>
  </icon>
  <servlet-name>InitParams</servlet-name>
  <display-name>InitParams Demo Servlet</display-name>
  <description>
    A servlet that shows use of both servlet- and
      webapp-specific init-params 
  </description>
  <servlet-class>InitParams</servlet-class>
  <init-param>
    <param-name>myParam</param-name>
    <param-value>
      A param for the Servlet:
      Forescore and seven years ago...
    </param-value>
  </init-param>
  <load-on-startup>25</load-on-startup>
</servlet>
Once you have your servlets in place, you may also need to add JavaServer Pages (JSPs) to your application. JSPs can be installed anywhere in a web application, except under
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Automatic Deployment
There are two ways of automatically deploying a web application:
  • Copy your WAR file or your web application's directory (including all of its content) to the $CATALINA_BASE/webapps directory.
  • Create an XML fragment with just the Context element for your web application, and place it in $CATALINA_BASE/webapps. The web application itself can then be stored anywhere on your filesystem.
If you have a WAR file, you can deploy it by simply copying the WAR file into the directory $CATALINA_BASE/webapps. The filename must end with an extension of war. Once Tomcat notices the file, it will unpack it into a subdirectory with the base name of the WAR file. It will then create a context in memory, just as though you had created one by editing Tomcat's server.xml file. However, any necessary defaults will be obtained from the DefaultContext element in Tomcat's server.xml file (see Chapter 7 for information on setting up a DefaultContext element).
Context entries can also appear as XML fragments. A context fragment is not a complete XML document, but just one Context element and any subelements that are appropriate for your web application. These files are like Context elements cut out of the server.xml file, hence the name context fragment.
For example, the Admin web application discussed in Chapter 2 is not listed in the server.xml file; instead, it is indicated through a context fragment in the file $CATALINA_BASE/webapps/admin.xml:
<!--
    Context configuration file for the Tomcat Administration
      Web App
 
    $Id: admin.xml,v 1.2 2001/10/27 18:56:23 craigmcc Exp $
-->
 
<Context path="/admin" docBase="../server/webapps/admin"
        debug="0" privileged="true">
 
  <Logger className="org.apache.catalina.logger.FileLogger"
          prefix="localhost_admin_log." suffix=".txt"
          timestamp="true"/>

</Context>
As another example, if we wanted to deploy the WAR file MyWebApp.war along with a realm for accessing parts of that web application, we could use this fragment:
<!--
  Context fragment for deploying MyWebApp.war
 -->
<Context path="/demo" docBase="webapps/MyWebApp.war"
        debug="0" privileged="true">
 
  <Realm 
    className="org.apache.catalina.realm.UserDatabaseRealm"
    resourceName="UserDatabase"
  />

</Context>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Manager Application
The Manager web application lets you manage your web applications through the Web. Of course, if anybody could manage everybody else's web applications, things might get a bit touchy, not to mention insecure. So you have to do a couple of things to make the Manager web application work, and work properly. You will probably need to add a Context entry for the Manager application in Tomcat's server.xml, and you must provide a username and password for access to the application.
The first step is to add a Context for the application in Tomcat's server.xml file:
 <!-- Manager (Tomcat) -->
        <Context path="/manager" docBase="manager"
            debug="0" privileged="true"/>
In Tomcat 4.1.x, there is an auto-deployment Context fragment distributed with Tomcat, so you don't even need to add the context. This step is necessary only on Tomcat 4.0.x versions.
You must then add a user to access the application. If you're using a UserDatabaseRealm, you'll need to add the user to the tomcat-users.xml file, which is discussed more fully in Chapter 2. For now, just edit this file, and add a line like this after the existing user entries (changing the password to something a bit more secure):
<user name="iadmin" 
      password="deep_dark_secret"  
      roles="manager" 
/>
Also make sure the role named manager is defined in your users database. The next time you restart Tomcat, you will be able to use the Manager web application.
The Manager application is actually designed for use within another program. Unmodified, it just generates a list of the web applications you have deployed, and it depends on servlet parameters for its codes; if you wish to use it like this, see the documentation that comes with Tomcat. We find it a bit laconic. It just prints this:
OK - Listed applications for virtual host localhost 
/webserver:running:0 
/javacook:running:0 
/darian:running:0 
/seating:running:0 
/openbsd:running:0 
/jabadot:running:0 
/manager:running:0
For each context, it prints the context name, regardless of whether that context is running, and the number of sessions (concurrent users) active for the context. Not a very pretty listing, but remember that it is intended for parsing by a program, not reading by a human.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Automation with Jakarta Ant
If you are changing your web application periodically and have to perform these various steps for deployment often, you will probably want to automate the process, rather than retyping the jar (and maybe copy/cp) command each time. Here we show you how to do so using Ant, a Jakarta build tool that is also used in Chapter 9. Of course, you can also use any other tool you like—such as make, Perl, a shell script, or a batch file—but Ant is becoming the standard tool for this purpose in the Java and Tomcat communities, so it's probably good to know the rudiments of Ant.
Ant automates the running of other programs. More precisely, Ant automates Java-related processing; it can run non-Java programs, but benefits from being able to do a great deal of processing just by running Java classes. Since Ant is written in Java, it already has a JVM available, so running other Java functions (including the standard Java compiler) is pretty fast because the JVM is already fired up. Ant also comes with a large library of built-in tasks for common operations, including dealing with TAR, JAR, ZIP, GZIP, and other file formats—usually without resorting to running external programs. That is, it contains Java classes that can read and write files in these and other formats, as well as copy files, compile Java programs (including servlets), and much more.
Ant reads build files written in XML, typically named build.xml, for its directions. An Ant build file contains one project definition and any number of targets (which are analogous to subroutines), one of which is the default target. A target is one unit of work: compiling some servlets, building a JAR file, or copying the JAR file. On the Ant command line, you can execute any target by name; if you don't name one, the default target is run.
Ant has built-in tasks for dealing with JAR/WAR files and copying files. Example 3-2 is an example build.xml from one of my web applications, slightly tailored for use here.
Example 3-2. Ant build file (build.xml) for creating a WAR file
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 4: Tomcat Performance Tuning
Once you have Tomcat up and running, you will likely want to do some performance tuning so that it serves requests more efficiently on your box. In this chapter, we give you some ideas for performance tuning the underlying Java runtime and the Tomcat server itself.
The art of tuning a server is complex. It consists of measuring, understanding, changing, and measuring again. The basic steps in tuning are:
  1. Decide what needs to be measured.
  2. Decide how to measure.
  3. Measure.
  4. Understand the implications of what you learned.
  5. Tinker with the configuration in ways that are expected to improve the measurements.
  6. Measure and compare with previous measurements.
  7. Go back to step 4.
Note that, as shown, there is no "exit from loop" clause. This is perhaps representative of real life, but in practice you will need to set a threshold below which minor changes are insignificant enough that you can get on with the rest of your life. You can stop adjusting and measuring when you believe you're close enough to the response times that satisfy your requirements.
To decide what to tune for better performance, you should do something like the following:
  1. Set up your Tomcat as it will be in your production environment. Try to use the same hardware, OS, database, etc. The closer it is to the production environment, the closer you'll be to finding the bottlenecks that you'll experience in your production setup.
  2. On a separate machine, install and configure the software that you will use for load testing. If you run it on the same machine that Tomcat runs on, you will skew your test results.
  3. Isolate the communication between your load-tester machine and the machine you're running Tomcat on. If you run high-traffic tests, you don't want to skew those tests by involving network traffic that doesn't belong in your tests. Also, you don't want to bring down machines that are uninvolved with your tests due to the heavy traffic. Use a switching hub between your tester machine and your mock production server, or use a hub that has only those two machines connected.
  4. Run some load tests that simulate the various types of high-traffic situations you expect your production server to have. Additionally, you should probably run some tests with
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Measuring Web Server Performance
Measuring web server performance is a daunting task, but we give it some attention here and also point you to more detailed resources. Unlike simpler tasks—such as measuring the speed of a CPU, or even a CPU and programming language combination—there are far too many variables involved in web server performance to do it full justice here. Most measuring strategies involve a "client" program that pretends to be a browser but actually sends a huge number of requests, more or less concurrently, and measures the response times. Are the client and server on the same machine? Is the server machine running anything else at the time of the tests? Are the client and server connected via a gigabit Ethernet, 100baseT, 10baseT, or 56KB dialup? Does the client ask for the same page over and over, or pick randomly from a large list of pages? (This can affect the server's caching performance.) Does the client send requests regularly or in bursts? Are you running your server in its final configuration, or is there still some debugging enabled that might cause extraneous overhead? Does the "client" request images or just the HTML page? Are some of the URLs exercising servlets and JSPs? CGI programs? Server-Side Includes? We hope you see the point: the list of questions is long and almost impossible to get exactly right.
The point of most web load measuring tools is to request a page a certain (large) number of times and tell you exactly how long it took (or how many times per second the page could be fetched). There are many web load measuring tools; see http://www.softwareqatest.com/qatweb1.html#LOAD for a list. A few measuring tools of note are the Apache Benchmark (ab, included with distributions of the standard Apache web server), Jeff Poskanzer's http_load from Acme Software (see http://www.acme.com/software/http_load), and JMeter from Apache Jakarta (see http://jakarta.apache.org/jmeter). The first two tools and JMeter are at opposite ends of the spectrum in terms of complexity and functionality.
There seems to be only light support for web application authentication in these web performance tester tools. They support sending cookies, but some may not support receiving them. And, whereas Tomcat supports several different authorization methods (basic, digest, form, and client-cert), these tools tend to support only HTTP basic authentication. The ability to closely simulate the production user authentication is an important part of performance testing because the authentication itself often does change the performance characteristics of a web site. Depending on which authentication method you are using in production, you might need to find different tools from the previously mentioned list (or elsewhere) that support your method.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
External Tuning
Once you have an idea of how your application and Tomcat instance respond to load, you can begin some performance tuning. There are two basic categories of tuning detailed here:
External tuning
Tuning that involves non-Tomcat components, such as the operating system that Tomcat runs on and the Java virtual machine running Tomcat.
Internal tuning
Tuning that deals with Tomcat itself, ranging from changing settings in configuration files to modifying the Tomcat source code itself. Modifications to your application would also fall into this category.
In this section, we detail the most common areas of external tuning, and then move on to internal tuning in the next section.
T omcat doesn't run directly on a computer; there is a JVM and an operating system between it and the underlying hardware. There are relatively few full-blown Java virtual machines to choose from for any given operating system, so most people will probably stick with Sun's or their own system vendor's implementation. One thing you can do is ensure that you have the latest release, since Sun and most vendors do work on improving performance between releases. Some reports have shown a 10 to 20 percent increase in performance with Tomcat running on JDK 1.4 over JDK 1.3. See Appendix A for information about which JDKs may be available for your operating system.
And what about the OS? Is your server operating system optimal for running a large, high-volume web server? Of course, different operating systems have very different design goals. OpenBSD, for example, is aimed at security, so many of the limits in the kernel are set low to prevent various forms of denial-of-service attacks (one of OpenBSD's mottoes is "Secure by default"). These limits will most likely need to be increased to run a busy web server.
Linux, on the other hand, aims to be easy to use, so it comes with the limits set higher. The BSD kernels come out of the box with a "Generic" kernel; that is, most of the drivers are statically linked in. This makes it easier to get started, but if you're building a custom kernel to raise some of those limits, you might as well rip out un-needed devices. Linux kernels have most of the drivers dynamically loaded. On the other hand, memory itself is getting cheaper, so the reasoning that led to loadable device drivers is less important. What is important is to have lots and lots of memory, and to make lots of it available to the server.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Internal Tuning
Content preview·