InformIT

Tomcat 5 Administration Basics

Date: Oct 1, 2004

Sample Chapter is provided courtesy of Sams.

Return to the article

In this chapter, you'll learn some of the ways to run Tomcat, the popular Java application server, and find out about Tomcat resources and configuration. In the exercises, you'll create a database connection pool to use in a new Java Server Page (JSP) that displays a list of Tomcat resources stored in a database.

In This Chapter

Defining Tomcat administration is a bit nebulous. As with many enterprise applications, administration means anything from starting and stopping to managing related resources that Tomcat depends on. I'm going to start by defining some of the things that might be part of Tomcat administration for you. Some are obvious; others really depend on your situation. In the last chapter, I already talked about one of them, configuration. In this chapter, we're going to start by looking at some of the ways to run Tomcat. Then, we'll spend the bulk of the time discussing Tomcat resources and configuring it to create a database connection pool, which we'll use in a new Java Server Page (JSP) that displays a list of Tomcat resources stored in a database. In the next chapter, I'll continue to expand the discussion of administration by dealing with security.

Introduction

Table 3.1 lists some of the things that, in my experience, fall into the purview of Tomcat administration. Again, not all might apply to you. Then again, there might be things you do that I don't mention.

Table 3.1 Tomcat Administration Tasks

Task

Notes

Installation/upgrade

Obvious, although part of this task implies some kind of acceptance testing for new versions prior to upgrade. We started this task in Chapter 1, "Tomcat Quickstart," but we'll expand on it in Chapter 17, "Administering Tomcat."

Running

Includes starting, stopping, and autostarting Tomcat. Covered here a bit in this chapter, but mostly in Chapter 17.

Basic configuration

I like to consider the setup or basic configuration of a Tomcat installation its own task, although it is usually lumped in with the installation task. Part of this task is what I called productionalizing the distribution, which we started in the last chapter.

Application administration

This task covers deployment, upgrade, and general ongoing maintenance of the application hosted by your Tomcat installation.

Monitoring

Covers error, load, and resource monitoring. Don't deploy without it!

Resource administration

A broad topic because it deals with the configuration of the resources required by Tomcat or its applications. This area might be as simple as configuring Tomcat to access these resources, as with an existing database, or as complex as installing, configuring, and setting up those resources as well.

Security

This task might be a narrow or broad task. If you have an existing security plan and infrastructure, it might be easy to integrate Tomcat into it. If you do not, this task might entail at least the basic development of such an infrastructure.

Web server integration

Most production Tomcat installations front Tomcat with a Web server like Apache or Internet Information Services (IIS). This I cover in Chapter 20, "Tomcat—Web Server Integration."


Now let's talk about running Tomcat.

Running Tomcat 5

So far, I've had you run Tomcat by typing catalina run. Some of you already familiar with Tomcat might wonder why I chose that method. As I pointed out before, I like it because if I have any startup errors, I get them in the same console window I used to type the command. For development, or for the initial setup of a Tomcat instance, it is good practice, but for production use, you generally choose another method.

Tomcat 5 bin files

Before I discuss the options, take a look at the contents of the bin directory. Figure 3.1 shows what's inside.

Figure 3.1Figure 3.1 Tomcat 5 bin directory contents.

Looks daunting, doesn't it? Well, if I group files together, it is not so bad.

First, there are a few jar files, or Java libraries, which Tomcat uses when it starts. They are described in Table 3.2.

Table 3.2 Tomcat Startup Jars

Jar

Description

bootstrap.jar

Contains the basic launcher class files for Tomcat.

commons-daemon.jar

A series of classes from the Jakarta Commons project for daemonizing a Java program.

commons-launcher.jar

A Java launcher program that is being split off from the Tomcat project and moved under Commons.

commons-logging-api.jar

An application programming interface (API) for logging that allows Tomcat to use any logging package which follows this API.


NOTE

If you are not familiar with the Jakarta Commons project, http://jakarta.apache.org/commons/, it is a project to create reusable Java components. There are a number of available components for beans, logging, connection pooling, collections, and so on. Many of these components owe their origins to Tomcat, so don't be surprised to see examples involving Tomcat. But the Tomcat developers found them to be useful enough to live in their own project space. Check them out! It might save you some valuable time on one of your projects.

Next, we can identify the main shell scripts, catalina.bat and catalina.sh, which we have already been using. They are called, in turn, by a few other scripts, shown in Table 3.3.

Table 3.3 Tomcat Startup Scripts

Script

Description

catalina.bat/.sh

Main Tomcat control script

shutdown.bat/.sh

A convenience wrapper that calls the main script with the stop command

startup.bat/.sh

A convenience wrapper that calls the main script with the start command


There are two Windows executables available for installing Tomcat as a service: tomcat.exe and tomcatw.exe. The only difference is that the latter runs a graphical version.

The launcher is a new concept in Tomcat 5. It used Apache Ant to start and stop Tomcat, as well as to invoke various Tomcat tools. This method uses the LauncherBootstrap.class, catalina.xml, launcher.properties, and *-using-launcher* files.

Table 3.4 describes a number of other files—utility scripts mostly—in the bin directory.

Table 3.4 Miscellaneous bin Files

File

Description

cpappend.bat

Windows shell script for building a CLASSPATH variable.

digest.bat/.sh

Script for digesting passwords (see next chapter, in the section "Digesting Passwords").

jsvc.tar.gz

A package for running Tomcat as a daemon (see Chapter 17).

setclasspath.bat/.sh

Script for building the CLASSPATH variable—called by catalina.bat/.sh.

tool-wrapper*

Scripts for running tools or other Java executables that need the same common class loader as Tomcat. Used, for example, to run the digest.bat/.sh script.


Tomcat 5 Run Options

Now I can talk about the options for running Tomcat. Basically, you have three: you can start Tomcat manually on the command line and run it as an application until you stop it, as you have been doing; you can start Tomcat as a daemon so that it starts automatically on machine boot; and you can start Tomcat with the Ant-based launcher. I discuss the latter in Chapter 17, "Administering Tomcat."

Running Tomcat 5 Manually

If you are happy starting Tomcat the way I showed earlier, you can continue to do so. But if you'd prefer the "standard" way, you can type the following on Unix:

startup.sh

Use the following on Windows:

startup

Note that startup simply invokes either catalina.bat or catalina.sh with the start argument.

Similarly, for stopping Tomcat, type the following on Unix:

shutdown.sh

Type this on Windows:

shutdown

In this case, the command invokes either catalina.bat or catalina.sh with the stop argument.

Running Tomcat 5 Automatically

In any production system, you want Tomcat to start when the machine boots and run as a daemon or unattended, system-owned process. On Unix, this means you'll typically create a startup script that the operating system (OS) will execute on the boot and shutdown of the machine. On Windows, you'll typically install Tomcat as a service for the same results.

The key to a daemon process is that the application can respond to signals from the OS and take appropriate startup or shutdown measures. In a Unix daemon, the application responds to signals sent by the OS. For a Windows daemon, or service, the application implements various methods that the OS makes calls to.

In fact, a Java process is not naturally a daemon: it is meant to be invoked by some client via the main method, which is the entry point to the application. To run a Java process as a daemon, you must provide a native wrapper around it that provides the proper interface to the OS so it can be run as a daemon. The Tomcat distribution comes with just such a wrapper, or daemonizer, from the Jakarta Commons Daemon project. This project actually has two different flavors: JSVC, the daemonizer for Unix, and procrun, for Windows. The latter comes by default with Tomcat, in the form of tomcat.exe and tomcatw.exe in the $CATALINA_HOME/bin directory. I'll save the discussion on JSVC for Chapter 17. For Unix, you also have the option to create a simple startup/shutdown script, which is what we'll do here.

Running Tomcat 5 Automatically on Unix

To run a process automatically on Unix, you usually create a startup script in a predefined directory that the OS can then find and execute as it starts up. As you probably know, Unix runs at various run or init levels. At each level, it starts various services. Although there are technically 10 possible levels, the ones that typically concern you are 1, which is when the system is running in single-user mode; 2, which is when the system is running in multi-user mode with Network File Service (NFS); 3, for full multi-user mode; and 5, which is full multi-user mode plus X Windows.

To tell Unix which services should start at which run level, a collection of directories under /etc/rc.d contains service startup scripts. Figure 3.2 shows a typical example (on a Linux server).

Figure 3.2Figure 3.2 Unix /etc/rc.d contents.

What you see is a directory for each Unix run level from 0 to 6, named rc[n].d, where [n] is the run level. The convention is to put the scripts in the init.d directory and then create symbolic links in the various run-level directories as appropriate. The convention also provides a way to determine the order of script execution at a particular run level: the symbolic links are named S[n][scriptname], where [n] is a two-digit number and [scriptname] is the actual name of the script in the /etc/rc.d/init.d directory that is being pointed to. There is a similar convention for stopping services, whereby Unix executes scripts as it descends through run levels. Scripts that need to execute to stop services are named K[n][scriptname], where [n] is a two-digit number and [scriptname] is the actual name of the script in the /etc/rc.d/init.d directory that is being pointed to. To make this work, you must configure the actual script to handle both start and stop situations, as you'll do in a minute.

You usually want Tomcat, or any Web server for that matter, to start at run level 3. I like to start Tomcat after any database server that my application depends on starts but before Apache starts (assuming that I am running Tomcat behind an Apache server). So I start by creating a script file called tomcat5 in /etc/rc.d/init.d that looks something like Listing 3.1.

Listing 3.1 Tomcat rc File

#!/bin/sh
#
# Startup script for Tomcat
#
 
case "$1" in
 start)
    echo -n "Starting Tomcat"
    JAVA_HOME="/usr/java/jdk1.3.1_08" ; export JAVA_HOME && 
/usr/tomcat5/bin/startup.sh
    ;;
 stop)
    echo -n "Stopping Tomcat"
    JAVA_HOME="/usr/java/jdk1.3.1_08" ; export JAVA_HOME && 
/usr/tomcat5/bin/shutdown.sh
    ;;
 restart)
    $0 stop
    $0 start
    ;;
 *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
esac
 
exit 0

This script expects to be called with one of three arguments: start, stop, or restart. All I do for the startup is set the $JAVA_HOME environment variable, which Tomcat needs, and then call startup.sh in the bin directory of the Tomcat installation. And that is all there is to it.

After you create the script, you need to create a symbolic link for it in the appropriate rc directory. Because I usually use rc3.d for Tomcat, I type

cd /etc/rc.d/rc3.d
ln -f ../init.d/tomcat5 K90tomcat5
ln -f ../init.d/tomcat5 S90tomcat5

What you are doing here is providing a startup link, S99tomcat5, which the OS will then call with the start argument. Because you want to gracefully shut down Tomcat when the machine stops, you'll also provide a shutdown link so that the OS will call with the stop argument. Obviously, both links point to the same script, which you've already coded to handle both arguments. Note too that I made the sequence number 90 because I want Tomcat to be one of the last things to start at run level 3. I make sure that MySQL (or whatever database I'm using) has a lower sequence number so it starts first. I also have Apache start after Tomcat by using a higher sequence number.

In Chapter 17, we'll go into building and using JSVC from the Commons Daemon project so that Tomcat can run as a true daemon.

Running Tomcat 5 as a Service on Windows

There are two ways you can install Tomcat as a daemon on Windows. The easiest is to download and execute the Windows installation of Tomcat. When you do, Tomcat is automatically installed as a service. The second option is to manually execute tomcat.exe in $CATALINA_HOME/bin.

Using the Tomcat Installer for Windows

Go back to the Tomcat binary download page, http://jakarta.apache.org/site/binindex.cgi, find the Tomcat 5 section, and download the *.exe distribution. After you download it, double-click to start the installation. You'll be prompted for the install location (by default, c:\Program Files\Apache Software Foundation\Tomcat 5.0), Java location, and a few other things. Once it is installed, however, you have a service now available called Apache Tomcat.

Manually Installing Tomcat as a Service

First, make sure you set the %JAVA_HOME% and %CATALINA_HOME% system environment variables in Control Panel, System, Environment Variables. Then, run the script shown in Listing 3.2.

Listing 3.2 Tomcat 5 Service Install Script

%CATALINA_HOME%\bin\tomcat //IS//Tomcat5 --DisplayName "Tomcat5" \
--Description "Tomcat5" --ImagePath "%CATALINA_HOME%\bin\bootstrap.jar" \
--StartupClass org.apache.catalina.startup.Bootstrap;main;start \
--ShutdownClass org.apache.catalina.startup.Bootstrap;main;stop \
--Java "%JAVA_HOME%\jre\bin\client\jvm.dll" \
--JavaOptions -Xrs \
--StdErrorFile "%CATALINA_HOME%\logs\stderr.log" \
--StdOutputFile "%CATALINA_HOME%\logs\stdout.log"

CAUTION

This script is JDK 1.4.2-specific. For JDK 1.3.x, you need to specify a different DLL in the --Java option, like this: --Java "%JAVA_HOME%\jre\bin\classic\jvm.dll" \.

When you type this command, put everything on one line; I show line breaks only for readability. What you are doing here is telling Windows to install Tomcat as the service named Tomcat5. This service will run tomcat.exe, which is really just procrun from Commons Daemon, with various parameters as indicated.

Because the service silently installed, you have to go to Control Panel, Administrative Tools, Services, and you should see the Tomcat service listed as Tomcat5, as defined in the script.

Running the Tomcat Service

From the Services window, Control Panel, Administrative Tools, Services, you can set Tomcat to start automatically when the machine boots. You can also manually start and stop Tomcat from this window, or if you prefer, you can run the service from the command line and start Tomcat with

net start Tomcat5

You can stop Tomcat with

net stop Tomcat5

Finally, if you want to remove the service, just type

"%CATALINA_HOME%\bin\tomcat //RS/Tomcat5 

Depending on how you installed the service, you might have a different name from mine. When I install it manually, I usually call the Tomcat 5 service Tomcat5, but the Windows installer calls it Apache Tomcat

Tomcat 5 Resources

Very few of us are going to run Tomcat in isolation. Yes, for getting a quick application up on a laptop, we might, but for most work, we at least need some sort of database connectivity, an email mechanism, and possibly hooks into a Lightweight Directory Access Protocol (LDAP) server or other authentication mechanism. We often call these things resources. But many other things are called resources. It is an oft-used term that can, depending on the context, mean just about anything related to the subject. When I first got started in developing complex Web applications, I was more than a little confused by the meaning of the term. In fact, very few of the terms we so easily throw around are well explained. So let's start with some definitions, which will serve us for the rest of the book.

Definitions

At the risk of being obvious, I want to clearly define a number of things, starting with the term Web application. What is a Web application? After all, this book is about writing and deploying these beasts, so we should have a clear idea of what we are talking about! Let me first, then, define a Web application as a package of functions whose job it is to provide responses to Web clients for a defined set of URLs. In other words, a Web application is configured to respond to one or more URLs, and deliver responses, depending on the requests. These responses usually return data or content, such as the content on a page showing the products a company sells. Typically, the primary function of a Web application is to return some sort of HTML data to the Web client, usually a browser. But what makes a Web application dynamic is that it can do other things besides serve content: it can perform certain tasks, such as inserting data into a database, authorizing a charge on a credit card, or sending an email.

With this understanding of what a Web application is, you can now look at what makes up a Web application. Broadly, I can define four types of things that make up a Web application. They appear in Figure 3.3.

Figure 3.3Figure 3.3 Web application contents.

First, a Web application has data—the data you write in your HTML files or put in your database. Second, it has logic, encapsulated in some programming language and executed to perform some task, including simply returning data to the client. Third, a Web application has a context—the environment in which it operates. This context or environment provides various parameters that might or might not affect the operation of the application itself. Finally, the application can have services that it requires to function, services that can either be within its environment or outside of it. In our case, the kinds of Web applications we are using are called J2EE Web applications because they use Java to generate the content.

Now, I can finally define a resource. Unfortunately, the term is often used to refer to all components of an application, such as static data files, class files, environment parameters, and external services. Because I like precision, I am going to limit my strict definition of a resource to a service on which Web applications depend. To make it clear, I refer to these resources as service resources. Thus, with this definition, a database server, LDAP server, email server, authentication mechanism, and so forth are all examples of service resources. The key factor is that these services are all outside of the Web application.

When a J2EE Web application runs inside a container, like Tomcat, that container provides various services to the Web application. For one thing, Tomcat loads the Web application, runs it, handles the TCP/IP communication with clients, and transports requests and responses between the clients and the application. In addition, Tomcat can read static files (HTML files, images, Cascading Style Sheets [CSS] files, and so on) and return the contents to the client. Tomcat can read JSPs, turn them into Java files, compile them, and execute them on behalf of the application. These tasks are indeed useful because it saves the application from having to do them. When it comes to resources, Tomcat is also a great friend to the Web application because it can make service resources available to it. These services can either be internal to Tomcat or external, in which case Tomcat handles the connectivity.

In Chapter 21, "Administering JNDI Resources," I talk about configuring Tomcat for various kinds of resources, but in this chapter, I'm only focusing on database resources. What we will do is create a JSP page that takes some data from a database table and presents it in HTML to the client. We'll keep things simple and just create a two-column table to hold a list of useful Tomcat-related URLs and their descriptions.

So we have four tasks ahead of us:

In this chapter, I use a MySQL database. If you want, you can use any database server of your choosing as long as you can get the Java drivers for it and you make any necessary changes to the syntax of my examples.

Installing MySQL

MySQL is currently the most popular open-source database server. With recent developments, it provides numerous features that make it competitive with the big commercial packages. It is probably the easiest database to get started on, and there is no end of examples in using MySQL with various Java applications like Tomcat.

Downloading MySQL

Start by going to the main download page, http://www.mysql.com, and downloading the latest version, 4.0.16 as of this writing, for the appropriate platform. The page http://www.mysql.com/downloads/mysql-4.0.html lists all the various options. For my Windows XP machine, I chose the file mysql-4.0.16-win.zip, and for my Linux server, I used mysql-standard-4.0.16-pc-linuxi686.tar.gz.

You also need the Java Database Connectivity (JDBC) drivers for MySQL, which is a separate download from http://www.mysql.com/downloads/api-jdbc-stable.html. The current version, 3.0.9, comes in a gzipped or zipped file. Pick whatever is easier.

Installing MySQL

Installing MySQL is pretty easy. For Windows, just double-click the downloaded zip file to open it and run the setup.exe file inside. You get a few prompts, but you can just take the defaults, which means MySQL is installed in c:\mysql.

For Unix, you need to be user root to install MySQL. You can unpack the distribution anywhere you want. I typically use the /opt directory, but you can choose something else. After you install it, you need to go through a few steps to get it up and running. First, add a mysql user and group by typing

groupadd mysql
useradd -g mysql mysql

Now, cd into the distribution and execute the script to set up all the system tables:

cd /opt/mysql-standard-4.0.16-pc-linux-i686
scripts/mysql_install_db
chown -R mysql data
chgrp -R mysql . 

Again, this is only for Unix installations. Note that my directory reflects my installation of version 4.0.16; adjust as appropriate for your location and version.

For the JDBC driver package, you have to unpack it as well and locate the actual jar file, which is called mysql-connector-java-3.0.9-stable-bin.jar. Remember the discussion of $CATALINA_HOME/common and $CATALINA_HOME/shared in the last chapter? There you learned that all objects in these directories are available to all Web applications, but that the former are also available to Tomcat, whereas the latter are not. Here is an example of a situation where you need to use the common directory. Because you want Tomcat to maintain the database connection pool, you must put the MySQL JDBC driver jar into $CATALINA_HOME/common/lib.

Before you start MySQL, I should point out that by default, the default login to MySQL is the admin user, root, and there is no password. Obviously, you need to productionalize this area, but that is not the point in this chapter. If you do decide to change any of it now, or if you are using an existing MySQL installation that has modified these defaults, then remember to substitute your login information in my examples.

Starting MySQL on Linux

Starting MySQL on Linux is easy: just go to the distribution directory and type

bin/mysqld_safe --user=mysql &

You get a couple of startup messages and then you should be able to type the following to enter the command-line utility:

bin/mysql

If you are successful, the command-line utility should respond with a message like the following:

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2 to server version: 4.0.16-standard

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> 

Then you know you are ready to go.

If for some reason you don't get this response, look in the data directory for an *.err file. Usually, this file tells you why the server could not start.

Starting MySQL on Windows

On Windows, it is easiest to install MySQL as a service and then start and stop the service. To do so, go to the bin directory of the MySQL installation, which is c:\mysql by default, and type the following:

mysqld --install

You should get the message Service successfully installed. Now, go into Services, under Control Panel, Administrative Tools; find the mysql service; and start it. If you'd like, you can set it to autostart when Windows starts.

Finally, you can test your installation by going back to the MySQL bin directory and typing

mysql

You should see the same response shown earlier, in the section "Starting MySQL on Linux."

Creating the Table

By default, MySQL comes with a system database called mysql. The first thing you have to do is create one for yourself, called unleashed. You do so by starting the client program and typing

create database unleashed

Now you can create and populate a table to hold various Tomcat-related resources. To simplify things, I've provided a sample SQL script, shown in Listing 3.3.

Listing 3.3 Table Create Script

use unleashed;


create table TomcatResources (
url varchar(255) not null,
title varchar(255) not null
);


insert into TomcatResources values (
'http://www.onjava.com/pub/a/onjava/2003/06/25/tomcat_tips.html? page=2&x-showcontent=off', 
'ONJava.com: Top Ten Tomcat Configuration Tips [Jun. 25, 2003]');

insert into TomcatResources values (
'http://jakarta.apache.org/tomcat', 
'The Jakarta Site - Apache Tomcat');

insert into TomcatResources values (
'http://www.moreservlets.com/Using-Tomcat-4.html', 
'Apache Jakarta Tomcat 4 and 5: Configuration and Usage Tutorial');

insert into TomcatResources values (
'http://www.jguru.com/faq/Tomcat', 
'Java Guru: Tomcat FAQ Home Page');

Because the point is to test database connectivity, I'm not loading up the table (yet) with the many considerable Tomcat-related resources on the Net!

To run this script, all you have to do is save it as something like unleashed.sql and type

mysql < unleashed.sql

This creates and populates your table. If you want to make sure, go back into the command-line utility, change databases, and select from the table:

use unleashed;
select * from TomcatResources;

With our database and table ready, we can now hook it up to Tomcat.

Creating the Database Connection Pool

Now let's introduce Tomcat to your database. We do so by creating a database connection pool that is actually a JNDI resource. JNDI is a J2EE technology that I talk more about in Chapter 21, "Administering JNDI Resources." Essentially, JNDI is a directory-like listing of resources maintained by a provider and available for lookup and access by a client. In our case, Tomcat serves as the provider, and our application (just the JSP, in this case) is the client. JNDI works by assigning resources names that the client can use to retrieve a handle to the resource itself.

When you create a JNDI-accessible database connection pool in Tomcat, you must define it in $CATALINA_HOME/conf/server.xml. As we'll see in Chapter 21, there are various places where you are allowed to define your pool. You can define it at the top level, thereby making it available to all hosts and host applications; at the virtual host level; and at the application or context level. The key determining factor here is scope: who needs your pool? Because we are just getting started, we'll keep your definition at the application level, which means we must now edit the application definition file, $CATALINA_HOME/conf/Catalina/localhost/unleashed.xml. The revised file appears in Listing 3.4.

Listing 3.4 Revised unleashed.xml

<Context path="/unleashed" docBase="unleashed" debug="0">

 <Logger className="org.apache.catalina.logger.FileLogger"
  prefix="localhost_unleashed_" suffix=".log"
  timestamp="false"/>

 <Resource name="jdbc/unleashed" auth="Container"
  type="javax.sql.DataSource"/>
 <ResourceParams name="jdbc/unleashed">
  <parameter><name>username</name><value>root</value></parameter>
  <parameter><name>password</name><value></value></parameter>
  <parameter><name>driverClassName</name>
   <value>org.gjt.mm.mysql.Driver</value></parameter>
  <parameter><name>url</name>
   <value>jdbc:mysql://localhost/unleashed</value></parameter>
 </ResourceParams>

</Context>

This code is a typical example of a JNDI resource definition. First, you need to define the resource itself. The fact that the type attribute is javax.sql.DataSource signals to Tomcat that it is a database connection pool. The name can be anything you want, but you typically use the prefix jdbc/ for connection pools. Also, it helps to use the database name as the rest of the name because it is clear at a glance what database this resource points to.

After the resource definition comes various parameters that apply to the resource. Obviously, each resource type has its own applicable parameters, some required and some not. For database pools, you need at least the four shown here: database user ID, database password, driver class name, and the JDBC URL that points to the database itself. Tomcat uses all four parameters to create connections to your database. The driver name is important because Tomcat will be looking in its classpath for that object. If you put the MySQL JDBC jar file in $CATALINA_HOME/common/lib, you're guaranteed that Tomcat will find it. Often, one of the biggest problems people have in setting up connection pools is in not having the JDBC jar file for their databases, having it but not in the right place (so it is not in Tomcat's classpath), or having the driver name wrong. Typically, the JDBC documentation specific to your database server will tell you what driver class name to use, as well as the format for the URL, another place where errors commonly occur. If you look at your URL, you'll notice that the syntax is basically host and database. You could also add a port number after the host, if you had your MySQL server running on something other than the default of 3306.

Also, remember to change the username and password parameters if you changed the MySQL defaults. You'll notice my password parameter is empty; that's because, again, the root user has no password by default. More parameters for database polls control their operation—minimum, maximum, rules for orphaned connections, and so on. You'll deal with all of them later, in Chapter 21.

Creating the JSP

We're two steps away from seeing whether everything works. First, we need to create a basic JSP page as shown in Listing 3.5. The logic of this page is to do a JNDI lookup on the connection pool and acquire a JDBC connection, which we can then use to retrieve the rows from the table. If you are not familiar with JDBC, just cut and paste away. Call this page resources.jsp and put it in the unleashed directory in your deployment directory.

Listing 3.5 resources.jsp

<html>
<%@ page language="java"
  import="javax.sql.*,javax.naming.*,java.sql.*" session="false"%>

 <head>
 <style type="text/css">
  <!--
  a { text-decoration: none }
  body { font-family: verdana, helvetica, sans serif; font-size: 10pt; }
  -->
 </style>
 </head>

 <body>
 <center>
  <h3>This is a test of a Tomcat-managed connection pool</h3>
 </center>

<%
  try {
    String jdbcname = "jdbc/unleashed";
    String cmd = "select title, url from TomcatResources order by title";
    Context ctx = new InitialContext();
    Context envCtx = (Context)ctx.lookup("java:comp/env");
    DataSource ds = (DataSource)envCtx.lookup(jdbcname);
    Connection conn = ds.getConnection();
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery(cmd);
    ResultSetMetaData rsmd = rs.getMetaData();
    int cols = rsmd.getColumnCount();

    out.println("<table border\"1\">");
    out.println("<tr bgcolor=\"lightGrey\">");

    for (int i = 1; i <= cols; i++) {
      out.println("<td align=\"center\" width=\"200\"><b>" +
        rsmd.getColumnName(i) + "</b></td>");
    }

    out.println("</tr>");

    while (rs.next()) {
      out.println("<tr>");

      for (int i = 1; i <= cols; i++) {
        out.println("<td align=\"left\">" +
            rs.getString(i) + "</td>");
      }

      out.println("</tr>");
    }

    out.println("</table>");
    conn.close();
    conn.close();
  } catch(Exception e) {
    out.println("Error: " + e);
    e.printStackTrace();
  }
%>

 </body>

</html>

One thing that is different between this JSP page and the index.jsp created earlier is that I had to add some imports to the page declaration. I imported javax.naming.* for the JNDI classes, javax.sql.* for the JNDI data source class, and java.sql.* for the JDBC classes. Another thing to note is that rather than intermingle HTML and Java code, I just created a single code block and used the println method on the out object to spit out the necessary HTML. The out object is one provided by default to JSP pages, and it stands for the ServletOutputStream object, with which the JSP writes data to the client. Sometimes, it is easier than mixing raw HTML with the Java code, although you do have to escape double-quotes, which can be a real pain.

The basic logic in this page is to retrieve a handle, which is called an InitialContext, to the JNDI naming environment. Note that we actually do two lookups: one to get the overall JNDI context, named as java:comp/env, and one to get the particular resource, which we named before as jdbc/unleashed. Remember I said that a JNDI lookup actually returns a handle to the resource. In this case, that handle is a javax.sql.DataSource object, from which we can then retrieve the connection that is wrapped inside. Then, we can do all your regular JDBC calls. You'll notice that I wrote a rather generic section of code that prints column names and headers based on the metadata returned by the result set. It is a useful way that you can use with any kind of select statement because it creates the table dynamically based on what is returned. If you want to see whether that is true, you can just replace the SQL statement I have with something that goes against one of your own tables. (You might also have to change the resource definition to point to another database, in this case.)

Testing

If you haven't already done so, you need to start or restart Tomcat. Then, you can browse to http://localhost:8080/unleashed/resources.jsp and see the results shown in Figure 3.4.

Figure 3.4Figure 3.4 Testing resources.jsp.

If you don't get this page, you have a couple of things to check. First, make sure you do have resources.jsp in the right directory. Second, and most important, you could see an error such as that shown in Figure 3.5.

This error is probably the most common error with Tomcat connection pools: the driver indicated in your resource definition in server.xml cannot be found. Note that my JSP spits out any exceptions to the browser, but not all code is so helpful. Many times, you'll have to look in the log files or the Tomcat console window for this error. You'll typically see a big stack trace, but somewhere buried should be this message. Then, you'll know that the JDBC jar file for your database is in the wrong place or missing. Correct the problem, restart Tomcat, and you'll be fine.

Figure 3.5Figure 3.5 Error page in resources.jsp.

Running Tomcat 4

Most of what I said about starting and stopping Tomcat 5 applies equally to Tomcat 4. Mainly, there are no launcher or JSVC daemon options in the latter

Tomcat 4 bin files

Figure 3.6 shows the contents of the Tomcat 4 bin directory.

As you can see, it is pretty much like Tomcat 5. There are no launcher files or JSVC jar. Unlike Tomcat 5, the 4 distribution comes with a few scripts to manually run the JSP compiler (Jasper).

Tomcat 4 Run Options

Again, most of what I discussed earlier works with Tomcat 4. You can create your rc file for Unix in the exact same way (changing the paths, of course). For installing Tomcat 4 as a service, however, the syntax is different because Tomcat 4 does not use procrun from Commons Daemon. When you use the Windows Installer, you can have it install Tomcat as a service, and then you are done. But if you want to do it manually, you have to use the script in Listing 3.6.

Figure 3.6Figure 3.6 Tomcat 4 bin directory contents.

Listing 3.6 Tomcat 4 Service Install Script

"%CATALINA_HOME%\bin\tomcat.exe "
-install "Tomcat5"
"%JAVA_HOME%\jre\bin\client\jvm.dll"
-Djava.class.path="%CATALINA_HOME%\bin\bootstrap.jar;%JAVA_HOME%\lib\tools.jar"
-Dcatalina.home="%CATALINA_HOME%"
-Xrs
-start org.apache.catalina.startup.Bootstrap -params start
-stop org.apache.catalina.startup.Bootstrap -params stop
-out "%CATALINA_HOME%\logs\stderr.log" 

CAUTION

Again, for JDK 1.3.x, the path to jvm.dll will be %JAVA_HOME%\jre\bin\classic\jvm.dll.

When you type this command, you get back the message

The service was successfully installed.

To verify, you can go to Control Panel, Administrative Tools, Services, and you should see the Tomcat service listed as Tomcat4, as defined in the script.

From the Services window, you can now set Tomcat to start automatically when the machine boots. You can also manually start and stop Tomcat from this window or, if you prefer, you can run the service from the command line and start Tomcat with

net start Tomcat4

You can stop Tomcat with

net stop Tomcat4

Finally, if you want to remove the service, just type

"%CATALINA_HOME%\bin\tomcat -uninstall Tomcat4 

Depending on how you installed the service, you might have a different name from mine. When I install it manually, I usually call the Tomcat 4 service Tomcat4, but the Windows installer calls it Apache Tomcat.

Tomcat 4 Resources

You'll be happy to know that the little connection pool example, using MySQL and JNDI, works exactly the same under Tomcat 4. If you didn't install MySQL before, do it now, and unpack the JDBC distribution. Copy the MySQL JDBC jar to $CATALINA_HOME/common/lib.

Assuming you created a context descriptor file for the unleashed application under Tomcat 4, you can make the same edits to it as we did for the unleashed.xml file in Tomcat 5. Don't forget to put both the <Resource> and <ResourceParams> blocks in the file.

Lastly, create the JSP file, if you haven't already. Start up Tomcat 4 and point your browser to http://localhost:8080/unleashed/resources.jsp. As before, if you get an error page, go over the location and names of all your files.

Conclusion

Let's look at what we've done. We took our productionalized Tomcat installation and added autostart capabilities so that Tomcat starts when the machine boots. We also got an introduction to Web application resources and what their management entails. In this case, we had to take care of the installation and configuration of the database, as well as the configuration of the JNDI data sources and actual coding of the application (just a JSP). Obviously, a larger IT shop probably has one or more people responsible for the database, so your job as a Tomcat administrator is somewhat smaller.

In the next chapter, I'll talk about a very important subject, security. We'll add some basic authentication and protection to your Tomcat installation. Then, we'll move on to application development, where I'll be discussing various methodologies and technologies for creating Tomcat applications.

800 East 96th Street, Indianapolis, Indiana 46240