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 plug-in 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 Apache and other web servers, such as Microsoft's Internet Information Server (IIS) and the iPlanet Enterprise Web Server.



mod_jk CVS

Originaly mod_jk was included in Tomcat 3.2 and next in 3.3 CVS repository, causing major headaches to maintain 2 set of identical code.
In 2001, all the connectors works was moved outside Tomcat 3.2/3.3 (for mod_jk) and Tomcat 4.0 (for mod_webapp) in a new repository called jakarta-tomcat-connectors, where all connector oriented development is now conducted.

In this repository you'll find native and java code, various native connectors like mod_jk (jk/native), mod_jk2 (jk/native2), mod_webapp, you'll find also the java side of these connectors (jk/java and webapp/java).

As such mod_jk could be used today by all of the ASF Tomcat Engine, 3.2.x, 3.3.x, 4.0.x, 4.1.x and 5.x.



Definitions and Terminology

In this document I am going to use a few terms, so let's define them:




Obtaining mod_jk

mod_jk can be obtained in two formats - binary and source.  Depending on the platform you are running your web server on, a binary version of mod_jk may be available.  It is recommended to use the binary version if one is available.  If the binary is not available, follow the instructions for building mod_jk from source.  Notes at the end of this section offer recommendations for specific platforms.

mod_jk Binaries

The binaries for mod_jk are now available, for several platforms, in a separate area as the Tomcat Binary Release.  The binaries are located in subdirectories by platform.  For some platforms, such as Windows, this is the typical way of obtaining mod_jk since most Windows systems do not have C compilers.  For others, the binary distribution of mod_jk offers simpler installation.

For example mod_jk 1.2.0 located at http://jakarta.apache.org/builds/jakarta-tomcat-connectors/jk/release/v1.2.0/bin/ contains the following:

linux/i386/ Contains mod_jk.so for Apache 1.3 for the standard API as well as EAPI and mod_jk.so for Apache 2.0
netware/ Contains the mod_jk.nlm and nsapi.nlm
rpms/
Contains the rpms (including sources and i386 architectures)
win32/ Contains the mod_jk.dll for Windows as well as other useful binaries.

Check the site for the latest binaries.

Note: The version of mod_jk is not dependent on the version of Tomcat.  The mod_jk 1.2.0 distribution will function correctly with Tomcat 3.2 up to Tomcat 5.

Building mod_jk

mod_jk is available in source distribution for all Windows and most Unix platforms.  The source for mod_jk live next to the Binary Distribution :

http://jakarta.apache.org/builds/jakarta-tomcat-connectors/jk/release/v1.2.0/src/ 

This directory is organized by Web Server name and version.  Each directory contains the source as well as the appropriate build scripts, make files, or project files.

Building mod_jk for NT

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

The steps that you need to take are:

  1. Change directory to the apache1.3 or apache2.0 source directory depending on your version of Apache.
  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 plug-in (mod_jk).

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

Building mod_jk for Unix

Building using configure

It is possible to use autoconf for configuration and installation.
To create jakarta-tomcat-connectors's autoconf script, you will need libtool 1.3.3 or higher, and autoconf 2.13 or newer.
Those tools will not be required if you are just using a package downloaded from apache.org, they are only required for
developers.

  To configure jakarta-tomcat-connectors run the following commands.
 
  ./buildconf.sh  (not required if there is allready the configure script)
./configure [autoconf arguments] [jakarta-tomcat-connectors arguments]
make

  It is possible to set CFLAGS and LDFLAGS to add some platform specifics:
  LDFLAGS=-lc ./configure -with-apxs=/home2/local/apache/bin/apxs

  Building for both Apache 1.3 and 2.0 using configure

  If you want to build mod_jk for Apache 1.3 and 2.0, you should :

  use configure and indicate Apache 1.3 apxs location (--with-apxs)
  use make
  copy the mod_jk binary to the apache modules location

  make clean (to remove all previously compiled modules)
  use configure and indicate Apache 2.0 apxs location,
  then make.

  ./configure --with-apxs=/usr/sbin/apxs
  make
  cp ./apache-1.3/mod_jk.so /usr/lib/apache
  make clean
  ./configure --with-apxs=/usr/sbin/apxs2
  make
  cp ./apache-2.0/mod_jk.so /usr/lib/apache2

  

  Examples using configure

  Apache2.0, JNI support:
  ./configure --with-apxs=/opt/apache2/bin/apxs --with-java-home=${JAVA_HOME} --with-java-platform=2 --enable-jni
  Apache 1.3, no JNI support:
  ./configure --with-apxs=/usr/sbin/apxs 

  Configure arguments

 

Apache related parameters



--with-apxs[=FILE]

FILE is the location of the apxs tool. Default is finding apxs in PATH.
It builds a shared Apache module. It detects automaticly the Apache version.
(2.0 and 1.3)

--with-apache=DIR

DIR is the path where apache sources are located.
The apache sources should have been configured before configuring mod_jk.
DIR is something like: /home/apache/apache_1.3.19
It builds a static Apache module.

--enable-EAPI

This parameter is needed when using Apache-1.3 and mod_ssl, otherwise you will get the error message:
"this module might crash under EAPI!" when loading mod_jk.so in httpd.
Not needed when --with-apxs has been used

--with-java-platform=VAL      

VAL is the Java platform 1 is 1.1.x and 2 is for 1.2 anf higher, should be guessed correctly.



JNI related parameters



--enable-jni
Build the JNI worker and so the build process will require some informations about your Java Environment

--with-java-home=DIR

DIR is the  patch to the JDK root directory. Something like: /opt/java/jdk12

--with-os-type[=SUBDIR]

SUBDIR is the os-type subdirectory, normaly configure should guess it correctly.

--with-arch-type[=SUBDIR]

SUBDIR is the arch subdirectory, normaly configure should guess it correctly.

--with-java-platform=VAL      

VAL is the Java platform 1 is 1.1.x and 2 is for 1.2 anf higher, should be guessed correctly.


Notes

Other Webservers

There are several Makefiles in the other directories under the TOMCAT_HOME/native/mod_jk/ directory.  You should also check the Tomcat documentation for specific information related to other web servers.


Configuring Apache

This section details the configuration that is required for the Apache Web Server to support mod_jk.

Removing mod_jserv directives

If you've previously 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.  The mod_jserv configuration directives are not compatible with mod_jk!

Configure Apache to use mod_jk

The simplest way to configure Apache to use mod_jk is to turn on the Apache auto-configure setting in Tomcat and put the following include directive at the end of your Apache httpd.conf file (make sure you replace TOMCAT_HOME with the correct path for your Tomcat installation:

Include TOMCAT_HOME/conf/jk/mod_jk.conf-auto

Example:

Include /usr/local/jakarta-tomcat/conf/jk/mod_jk.conf-auto

This will tell Apache to use directives in the mod_jk.conf-auto file in the Apache configuration.  This file is created by enabling the Apache auto-configuration as described in the configuring Tomcat section below [Configuring Tomcat].

NOTE:  If you plan to use the Tomcat-Apache auto-configuration, skip the rest of this section and continue with the Configuring Tomcat section.

Custom configurations can be created by enabling the auto-configuration and copying the TOMCAT_HOME/conf/jk/mod_jk.conf-auto file to your own configuration file, such as TOMCAT_HOME/conf/jk/mod_jk.conf-local.

The basic configuration is as follows:

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 info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

Assigning URLs to Tomcat

If you have created a custom or local version of mod_jk.conf-local as noted above, you can change settings such as the workers or URL prefix.

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 with /servlet as the second path componenet 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.

Configuring Apache to serve static web application files

If the Tomcat Host appBase (webapps) directory is accessible by the Apache web server, Apache can be configured to serve web application context directory static files instead of passing the request to Tomcat.

Caution: If Apache is configured to serve static pages for a web application it bypasses any security contraints you may have configured in your web application web.xml config file.

Use Apache's Alias directive to map a single web application context directory into Apache's document space for a VirtualHost:

# Static files in the examples webapp are served by apache
Alias /examples /export/home/web/host1/webapps/examples

JkMount /*.jsp ajp13
JkMount /*/servlet/ ajp13

Use the mod_jk JkAutoAlias directive to map all web application context directories into Apache's document space. Attempts to access the WEB-INF or META-INF directories within a web application context or a Web Archive *.war within the Tomcat Host appBase (webapps) directory will fail with an HTTP 403, Access Forbidden.

Example configuration for an Apache VirtualHost:

# Static files in all Tomcat webapp context directories are served by apache
JkAutoAlias /export/home/web/host2/webapps

JkMount /*.jsp ajp13
JkMount /*/servlet/ ajp13

Configuring Tomcat

Enabling Tomcat's Apache Auto-Config

In most simple cases Tomcat can generate the needed Apache configuration. You can configure Tomcat so that when it starts up it will automatically generate a configuration file for Apache to use mod_jk. Most of the time you don't need to do anything but include this file (appending "Include TOMCAT_HOME/conf/jk/mod_jk.conf-auto") in your httpd.conf, as shown in the previous section (Configuring Apache).

To configure Tomcat to generate the Apache auto-configuration add the following block to your TOMCAT_HOME/conf/server.xml file after <AutoWebApp ... />.

<ApacheConfig />

That's it, you can now start Tomcat and Apache and access Tomcat from the Apache server.

Note: Settings for mod_jk auto-configuration is new in Tomcat 3.3.  Older versions of Tomcat create the auto-config file without a directive in server.xml.  The new directive in Tomcat 3.3 allows for additional configuration options as detailed later in this section.  For older versions of Tomcat, refere to the documentation that came with that version.

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.

Note that 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/jk/mod_jk.conf-auto is generated when tomcat starts, so you'll need to start Tomcat before Apache. Tomcat will overwrite TOMCAT_HOME/conf/jk/mod_jk.conf-auto each startup so customized configuration should be kept elsewhere.  For example, copy  TOMCAT_HOME/conf/jk/mod_jk.conf-auto to TOMCAT_HOME/conf/jk/mod_jk.conf-local before making changes.  You'll need to startup Tomcat once to generate this file with your configuration for the first time.

It is also possible to specify the location of the auto generated files by setting options in the <ApacheConfig /> block.  The following details the syntax:

< ContextManager ... >
...
<ApacheConfig options />
...
< /ContextManager >

 where options can include any of the following attributes:

 Example:

...

<AutoWebApp dir="webapps" host="DEFAULT" />

<ApacheConfig confighome="/home/mydir" />

...

(Optional) Configuring Tomcat to use the Ajpv13 protocol

mod_jk can use either the original Ajpv12 protocol or the newer Ajpv13 protocol. Both protocols are enabled by default. The "Ajp13" Connection Handler in Tomcat will give you the benefit of a faster protocol and the ability to identify requests made via HTTPS.

The following block enables Ajpv13 in your TOMCAT_HOME/conf/server.xml file.
<RequestInterceptor
className="org.apache.tomcat.modules.server.Ajp13Interceptor"
port="8009"/>

The server.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.

(Optional) Defining "workers"

Configuring workers manually.

Workers are configured using the file TOMCAT_HOME/conf/jk/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.


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/jk/workers.properties
JkLogFile /usr/local/apache/logs/mod_jk.log
JkLogLevel info

# First Virtual Host. Request logging is enabled.
#
<VirtualHost 10.0.0.1:80>
DocumentRoot /web/host1
ServerName host1.apache.org
JkRequestLogFormat "%w \"%r\" %s %T"
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. Where can I get help/support for mod_jk?

A. The primary mechanism for support is through the mod_jk Documentation included in the doc directory.  Documentation is also available on the Apache Jakarta web site for Tomcat at http://jakarta.apache.org/builds/jakarta-tomcat-connectors/jk/doc/index.html.

For additional help, the best resource is the Tomcat Users Discussion list.  You should start by searching the mail list archives located at http://mikal.org/interests/java/tomcat/index.html before you post questions to the list.  If you are unable to locate the answer to your question in the archive, you can post questions about Tomcat or mod_jk to the user list for assistance.  Make sure that you include the version of Apache and Tomcat that you are using as well as the platform you are running on. http://jakarta.apache.org/site/mail.html

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

A. Now that mod_jk moved to jakarta-tomcat-connectors repository, the source and binaries for mod_jk are present in the jakarta-tomcat-connectors directory at jakarta.apache.org.  You'll find jk release at :  http://jakarta.apache.org/builds/jakarta-tomcat-connectors/jk/release/  .

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 it. There is more information in the workers.properties howto document, ajp12 is now deprecated. Also ajp13 is supported by all Apache Tomcat  including 3.2.x , 3.3.x, 4.0.x, 4.1.x and the new tomcat 5. Also others Servlet engine like jetty have support for Ajp13.

Q. Whenever I restart Tomcat, Apache locks up!

A. The Ajp13 protocol keeps an open socket between Tomcat and Apache. The latest release of mod_jk (the one found since Tomcat 3.3-m2 and J-T-C) handle the network failure. But with previous release of mod_jk, you may have to restart Apache as well.

Q. Why did exist two files mod_jk.so (-eapi ad -noeapi) in download dir for Linux ?

A. Many versions of Apache use of modified API, known at Extended API. For example, Apache using mod_ssl or Apache present in certains recent Linux distributions. So if you got such 'Extended Apache', you need to use mod_jk.so-eapi, or use mod_jk.so-noeapi for standard Apache. It's wise to avoid using EAPI modules on STD API Apache or to use standard API modules on EAPI Apache. Allways be sure to have the mod_jk.so for your version of Apache

Q. What's that message about 'garbled DSO ?'

A. It's related to Apache EAPI, the message 'mod_jk.so is garbled - perhaps this is not an Apache module DSO ?' just told you are trying to install a mod_jk.so DSO module that was compiled on an Apache using EAPI, like apache-mod_ssl or apache from Redhat distro 6.2/7.0 but your system use the standard apache with normal API.

Q. And the message about 'module might crash under EAPI! '

A. Also related to EAPI, the message '[warn] Loaded DSO /usr/lib/apache/mod_jk.so uses plain Apache 1.3 API, this module might crash under EAPI! (please recompile it with -DEAPI)', the mod_jk.so was compiled under normal Apache with standard API and you try to install the module on an Apache using EAPI.

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.

Q. APXS is getting an error during the build of mod_jk, like rc=0 or rc=255.  I tried all of the steps in the build section, what do I do now?

A. APXS is a Perl script that is created when you build the Apache web server from source.  Chances are that if you are getting these errors and you obtained Apache as a binary distribution, that APXS is not configured correctly for your system.  Your best bet is to get the Apache source from http://httpd.apache.org and build it yourself.  Use the following for a basic build (read the Apache docs for other options):
# cd /usr/local/src
# gzip -dc apache_1.3.19.tar.gz|tar xvf -
# cd apache_1.3.19
# ./configure --prefix=/usr/local/apache \
--enable-module=most \
--enable-shared=max
# make
# make install

Note: The above steps assume that you downloaded the Apache source and placed it in your /usr/local/src directory.

Q. Apache 2.0 complains about incorrect module version

A. Since Apache 2.0 API still change often, the Apache 2.0 teams decide to put in headers of compiled modules the Apache 2.0 version used to compile the module. At start time Apache 2.0 check that version in modules headers and stop if it detect that a module was compiled for another Apache 2.0 version. As such you should allways use modules compiled for the same Apache 2.0 version. This check may be removed if the future.

Q. JNI didn't works with Apache 1.3

A. JNI support require a multi-threaded environment which is not the case for Apache 1.3. You should verify if Apache 1.3 has been build with thread support and if not you could add the LoadModule "/usr/lib/libpthreads.so" in your httpd.conf. Also keep in mind that JNI is suited for multi-threaded servers and you should consider upgrading to Apache 2.0 to support JNI.

Q. JNI report that JVM couldn't be started under Linux

A. Under Linux, you should set some environment variables BEFORE launching your Apache server :
export LD_LIBRARY_PATH=$jre/bin:$jre/bin/classic:$LD_LIBRARY_PATH
Also some Linux distributions have enabled a GLIBC feature called 'floating stacks' which may not works with kernel less than 2.4.10 on SMP machines. You should disable floating stacks by exporting an environment variable :
export LD_ASSUME_KERNEL=2.2.5
You could have to update your service scripts, ie /etc/rc.d/init.d/httpd, to set these env vars before your httpd server starts.

Q. I've got a firewall between my WebServer and Tomcat who drop ajp13 connections after some times

A. Ajp13 use persistant connections where the traffic could be null if there is no request to be sent to Tomcat. Firewall used to drop inactive connections and will make your WebServer and Tomcat think the connection is valid. In mod_jk 1.2.0 a socket_keepalive property as been added to ajp13 settings, and you should take a look at it in workers.properties howto

Q. Under heavy load, I've got many threads in Tomcat even if my Apache Web Server handle much of the load

A. Under heavy load, Apache WebServer create many childs to handle the load, which will in turn create many connections to Tomcat to forward the requests they should handle. Apache WebServer will normally kill the childs/threads when the load decrease. But if the load is still there and even if only Apache handle the requests, ie static contents, the childs are kept and with them the ajp13 connections, even if they are no more used. In mod_jk 1.2.0 cache_timeout and socket_timeout properties as been added to close connections after some time, for more informations refer to workers.properties howto



Credits

This document was originally created by Gal Shachor

Revisions by (Alphabetical)

Mike Braden <mikeb@mwbinc.com>
Mike Bremford
Henri Gomez <hgomez@apache.org>
Glenn Nielsen
Chris Pepper

With help from countless others on the tomcat-dev and tomcat-user lists!

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