The Jakarta Project The mighty Tomcat - Meow!

Working with mod_jk

By Gal Shachor <shachor@il.ibm.com>

Table of Contents


What is mod_jk?

mod_jk is a replacement to the elderly mod_jserv. It is a completely new Tomcat-Apache plugin that handles the communication between Tomcat and Apache


Why mod_jk?

Several reasons:


What does it mean to me?

You will need to get to know a new simplified configuration mechanism. The advantage is that learning this mechanism will give you a head start if you want to deploy Tomcat on other web servers such as IIS and Netscape (oops, iPlanet).


Definitions and terminology

During this document I am going to use a few terms, so lets define them:

Term

Meaning

Worker process

A worker is a tomcat instance that is running to serve servlet requests coming from the web server. In most cases there is only a single worker (the one and only tomcat process) but sometimes you will run multiple workers to achieve load balancing or site partitioning. Each worker is identified to the web server by the host were it is located, the port where it listens and the communication protocol used to exchange messages.

In process worker

This is a special worker. Instead of working with a Tomcat process residing on another process, the web server opens a JVM and executes Tomcat inside the web server process address space. Our discussion in this document is not going to get into this special worker.

Web server plugin/tomcat redirector

For Tomcat to cooperate with any web server it needs an "agent" to reside in the web server and send him servlet requests. This is the web server plugin, and in our case the web server plugin is mod_jk. The redirector usually comes in the shape of a DLL/shared object module that you should plug into the web server.

Plugin configuration

We need to configure the web server plugin so that it will know where are the different Tomcat workers and to which of them it should forward requests. This information accompanied with some internal parameter such as the log level comprises the plugin configuration.

Web server configuration

Each web server has some configuration that defines how behave, e.g. on which port to listen, what files to serve, what web server plugins to load, etc. You will need to modify your web server configuration to instruct it to load the tomcat redirector.


Configuring Apache to use mod_jk

The configuration includes the following steps:

  1. Remove your old mod_jserv configuration. mod_jk and mod_jserv cannot coexist !!
  2. Obtaining mod_jk
  3. (optional) Configuring Tomcat to use the Ajpv13 protocol
  4. Defining workers for mod_jk (or selecting the quick start option)
  5. Configuring Apache to use mod_jk and configure mod_jk internals (or selecting the quick start option)
  6. Assigning URLs to be redirected to Tomcat (or selecting the quick start option)

1. Removing the mod_jserv directives

If you've already configured Apache to use mod_jserv, remove any ApJServMount directives from your httpd.conf. If you're including tomcat-apache.conf or tomcat.conf, you'll want to remove them as well - they are specific to mod_jserv.

2. Obtaining and building mod_jk

Binaries are available for Linux and Win32 under the bin directory where you obtained the Tomcat distribution file. For Linux, mod_jk is available as mod_jk.so. For Win32, mod_jk is available as mod_jk.dll. If there isn't a prebuilt mod_jk available or you wish to build your own copy, you can build it yourself from the source. First, download the Source Distribution for Tomcat. There are a large number of files in the download directory, but the only one you need is jakarta-tomcat.

On NT

The redirector was developed using Visual C++ Ver.6.0, so having this environment is a prereq if you want to perform a custom build.

The steps that you need to take are:

  1. Change directory to the apache1.3/apache2.0 source directory.
  2. Set an APACHE1_HOME environment variable which points to where your Apache is installed.
  3. Execute the following command:

    MSDEV mod_jk.dsp /MAKE ALL

    If msdev is not in your path, enter the full path to msdev.exe. Also, ApacheCore.lib is expected to exist in the APACHE1_HOME\src\CoreD and APACHE1_HOME\src\CoreR directories before linking will succeed. You will need to build enough of the Apache source to create these libraries.
  4. Copy mod_jk.dll to Apache's modules directory.

This will build both release and debug versions of the redirector plugin (mod_jk).

An alternative will be to open mod_jk.dsp in msdev and build it using the build menu.

On UNIX

For Apache

  1. Make sure you have Perl 5 installed. The apxs script used to build the module is written in Perl.
  2. Change directory to jakarta-tomcat/src/native/apache1.3 (or apache2.0).
  3. Run the apxs command that came with your apache distribution (hint: look in /usr/local/apache/bin, /usr/sbin, or wherever you intalled apache). Type the command all on one line.

    For Solaris:
    apxs -o mod_jk.so -DSOLARIS -I../jk -I/usr/java/include -I/usr/java/include/solaris -c *.c ../jk/*.c
    On some systems, this will build the module correctly, but will fail at runtime with a "symbol "fdatasync" not found". To fix, add -lposix4 just before the -c in the above command.

    For Linux:
    apxs -o mod_jk.so -I../jk -I/usr/local/jdk/include -I/usr/local/jdk/include/linux -c *.c ../jk/*.c
    Your build may fail because the object files from the ../jk directory have been compiled to the current directory, rather than their source directory. Running gcc -shared -o mod_jk.so *.o should finish the build.

    (If you've installed Java in another directory, adjust accordingly). For other *nixes you should be able to work it out, but remember that the order of the arguments to apxs is important!.
  4. Copy mod_jk.so to Apache's libexec directory

For other Webservers

There are several Makefiles in the other directories under the jakarta-tomcat/src/native directory.

3. (optional) Configuring Tomcat to use the Ajpv13 protocol

mod_jk can use either the original Ajpv12 protocol or the newer Ajpv13 protocol. If you choose the latter, you need to activate the "Ajp13" Connection Handler in Tomcat. This will give you the benefit of a faster protocol and the ability to identify requests made via HTTPS.

Add the following block to your TOMCAT_HOME/conf/server.xml file.
<Connector className="org.apache.tomcat.service.PoolTcpConnector">
  <Parameter name="handler" value="org.apache.tomcat.service.connector.Ajp13ConnectionHandler"/>
  <Parameter name="port" value="8009"/>
</Connector>
The servlet.xml file already has a block similar to this for Ajp12 connections on port 8007 (as delivered by mod_jserv). Even if you think you're only using Ajp13, you probably don't want to delete this connector - it's required to shut down Tomcat.

4. Defining "workers"

Quick start?

In most of simple cases Tomcat can generate the needed Apache configuration. When Tomcat starts up it will automatically generate a configuration file for Apache in TOMCAT_HOME/conf/mod_jk.conf-auto. Most of the time you don't need to do anything but include this file (appending "Include TOMCAT_HOME/conf/mod_jk.conf-auto") in your httpd.conf. That's it, you can now start Tomcat and Apache and access Tomcat from the Apache server.

If you have special needs, for example mounting URL prefixes that are not the default, you can use this file as a base for your customized configuration and save the results in another file. If you manage the Apache configuration yourself you'll need to update it whenever you add a new context.

Tomcat 3.2: you must restart tomcat and apache after adding a new context; Apache doesn't support configuration changes without a restart. Also the file TOMCAT_HOME/conf/mod_jk.conf-auto is generated when tomcat starts, so you'll need to start Tomcat before Apache. Tomcat will overwrite TOMCAT_HOME/conf/mod_jk.conf-auto each startup so customized configuration should be kept elsewhere.

Configuring workers manually.

Workers are configured using the file TOMCAT_HOME/conf/workers.properties. There is a great deal of information in the workers.properties howto document, and you should really look at that first. If you're in a hurry however, you can probably get away with editing the file workers.properties and setting the workers.tomcat_home, workers.java_home and ps variables to the correct values for your system.

5. Configure Apache to use mod_jk

Configuring Apache to use mod_jk is done using the Apache server configuration directives; to get you started, look at the auto-generated mod_jk.conf-auto available in Tomcat's conf directory.

A simple example would be to include the following lines in your httpd.conf file:
LoadModule    jk_module  libexec/mod_jk.so
AddModule     mod_jk.c
JkWorkersFile /usr/local/jakarta-tomcat/conf/workers.properties
JkLogFile     /usr/local/apache/logs/mod_jk.log
JkLogLevel    warn

6. Assigning URLs to Tomcat

Use mod_jk's JkMount directive to assign specific URLs to Tomcat. In general the structure of a JkMount directive is:

JkMount <URL prefix> <Worker name>

For example the following directives will send all requests ending in .jsp or beginning with /servlet to the "ajp13" worker, but jsp requests to files located in /otherworker will go to "remoteworker".

JkMount /*.jsp ajp13
JkMount /servlet/* ajp13
JkMount /otherworker/*.jsp remoteworker
You can use the JkMount directive at the top level or inside <VirtualHost> sections of your httpd.conf file.
You're done! You should now be able to start Tomcat and apache and have them cooperate to serve servlets and JSP files.

An example configuration

Here's an example configuration which probably reflects many real-world setups. A site is using Tomcat and Apache with two virtual hosts (one of them using HTTPS as well, which we're assuming is being handled by mod_ssl).

URLs ending in .jsp and beginning with /servlet are handled by Tomcat, the rest are handled by Apache. The files for each Host are server out of /web/host1 and /web/host2 respectively.

The example are over-simplified and incomplete but should get you started. Also note the virtual host setup is new in Tomcat 3.2 - this example won't work with Tomcat 3.1.

.
.
<Connector className="org.apache.tomcat.service.PoolTcpConnector">
  <Parameter name="handler" value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
  <Parameter name="port" value="8007"/>
</Connector>

<Connector className="org.apache.tomcat.service.PoolTcpConnector">
  <Parameter name="handler"  value="org.apache.tomcat.service.connector.Ajp13ConnectionHandler"/>
  <Parameter name="port" value="8009"/>
</Connector>

<Host name="host1.apache.org">
  <Context path="" docBase="/web/host1" debug="0"/>
</Host>
<Host name="host2.apache.org">
  <Context path="" docBase="/web/host2" debug="0"/>
</Host>
.
.
Table 1 - Excerpt from server.xml showing the Ajp13 Connector and two virtual hosts.

# Setup for Solaris system
#
workers.tomcat_home=/usr/local/jakarta-tomcat
workers.java_home=/usr/java
ps=/
worker.list=ajp12, ajp13

# Definition for Ajp13 worker (Ajp12 left to readers imagination)
#
worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
Table 2 - Excerpt from workers.properties showing the Ajp13 worker

# Load mod_jk
#
LoadModule    jk_module  libexec/mod_jk.so
AddModule     mod_jk.c

# Configure mod_jk
#
JkWorkersFile /usr/local/jakarta-tomcat/conf/workers.properties
JkLogFile     /usr/local/apache/logs/mod_jk.log
JkLogLevel    warn

# First Virtual Host.
#
<VirtualHost 10.0.0.1:80>
  DocumentRoot /web/host1
  ServerName host1.apache.org
  JkMount /*.jsp ajp13
  JkMount /servlet/* ajp13
</VirtualHost>

# Second Virtual Host. Also accessible via HTTPS
#
<VirtualHost 10.0.0.2:80>
  DocumentRoot /web/host2
  ServerName host2.apache.org
  JkMount /*.jsp ajp13
  JkMount /servlet/* ajp13
</VirtualHost>

<VirtualHost 10.0.0.2:443>
  DocumentRoot /web/host2
  ServerName host2.apache.org
  SSLEngine On
  JkMount /*.jsp ajp13
  JkMount /servlet/* ajp13
</VirtualHost>

Table 3 - Excerpt from Apaches httpd.conf showing JK directives.

Troubleshooting and F.A.Q.s

Q. I can't find mod_jk anywhere. Where is it?

A. You need to download the Source Distribution of Tomcat and build it yourself. See this section for more information.

Q. Which protocol should I use? Ajp12 or Ajp13?

A. Ajp13 is a newer protocol, it's faster, and it works better with SSL. You almost certainly want to use that. There is more information in the workers.properties howto document

Q. Whenever I restart Tomcat, Apache locks up!

A. The Ajp13 protocol keeps an open socket between Tomcat and Apache. When you restart Tomcat, you need to restart Apache as well.

Q. Where can I get more information?

A. The workers.properties howto document has considerably more in-depth information than this one, and is worth a look. You could also try searching the mailing list archives for "mod_jk" or look at the source.

Credits

This document was created by Gal Shachor, and was revised by Mike Bremford with help from the countless many on the tomcat-dev and tomcat-user lists!

Copyright ©1999-2000 The Apache Software Foundation
Legal Stuff They Make Us Say
Contact Information