Apache Tomcat mod_jk Connector Configuration Made Simple

In this article, we provide a comprehensive overview of the Apache mod_jk connector, including configuration information, use scenarios, solutions to common problems, and a comparison of mod_jk to other similar connector components.

Table Of Contents

I. The Basics - What is mod_jk?

II. Common Use Scenarios - Why connect HTTPD and Tomcat?

III. Installation and Configuration

IV. Alternatives to mod_jk

I. The Basics - What is mod_jk?

The mod_jk connector is an Apache HTTPD module that allows HTTPD to communicate with Apache Tomcat instances over the AJP protocol.  The module is used in conjunction with Tomcat's AJP Connector component.

About Connectors

Apache Tomcat uses Connector components to allow communication between a Tomcat instance and another party, such as a browser, server, or another Tomcat instance that is part of the same network.  For example, the HTTP connector listens for requests over the HTTP/1.1 protocol on various TCP ports, and forwards them to the Engine associated with processing the request.

Using the AJP connector, Apache Tomcat instances can exchange data with mod_jk enabled instances of Apache HTTPD, using the AJP protocol.  Implementations of mod_jk are also available for integration with IIS and NES/iPlanet/Sun, but are less widely used.

About AJP

AJP, an acronymn for Apache Jserv Protocol, is a binary version of HTTP that is optimized for communication between Apache HTTPD and Apache Tomcat over a TCP connection.  The current version of the AJP protocol is 1.3, referred to by the standard name ajp13.  ajp13 extends the earlier mod_jserv and ajp12 modules, offering significant speed improvements and SSL support.

Other than the data format, differences between the standard HTTP and AJP protocols include more persistent connections (to avoid unnecessary socket creation) and a focus on connection reuse over a series of request/response cycles.  

A detailed description of the AJP protocol can be found on the Tomcat Connectors sub-project site.

II. Common Use Scenarios - Why connect HTTPD and Tomcat?

One question often asked by new Tomcat users is why Tomcat and HTTPD would need to communicate at all.  After all, one of the features that makes Tomcat so flexible is its ability to function as a standalone web server and application server, thanks to the Coyote component.  

There are a number of reasons why you might need HTTPD and Tomcat to talk to one another.  

In the early days of Tomcat, one of the most common reasons to connect the two servers was to allow HTTPD to serve static content, freeing up Tomcat to process dynamic requests.  However, performance improvements have made serving static content using Tomcat just as fast as on HTTPD (and sometimes faster, when the elimination of the extraneous connection is factored in). 

However, there are still plenty of good reasons why you might want to use the two together.

Clustering, Load Balancing, and Security

HTTPD and mod_jk can be used to balance server load across multiple Tomcat instances, or divide Tomcat instances into various namespaces, managed by HTTPD.

Apache HTTPD Modules and Extensions

Apache HTTPD has been the most popular web server in the world since 1996.  At this point, the number of modules that are available to extend its functionality is staggering.  Need CGI?  Adding it to Tomcat is going to take some elbow grease, but adding it to Apache is just a matter of installing downloading and installing a single module.  Apache also can handle many different "decorations" - rewrites of headers, URLs, and more. 

Socket Error Handling

Unlike Tomcat, Apache HTTPD can run natively on a system, rather than within a cross-platform JVM.  For this reason, HTTPD has an advantage when it comes to handling socket errors (i.e. dropped/invalid connections, invalid IPs, etc), as socket optimization practices differ significantly from operating system to operating system.   

Security

Tomcat and HTTPD are different projects, but in some areas - security, for example - their functionality overlaps.  
In these cases, some users may decide to delegate these tasks to HTTPD.  Usually, this decision is based on the fact that HTTPD has a much larger community than Tomcat, and thus has many more 'tricks up its sleeve' when it comes to these areas.  
While this isn't an unreasonable line of logic, Tomcat is not inherently less secure than HTTPD.  In fact, according to Apache, there has never been a reported case of data loss or damage due to a malicious attack on a Tomcat instance - not even one.  
Ultimately, the decision to use HTTPD to handle security should be based on your specific use scenario.  If you are facing a problem that has no existing solution in the Tomcat community, but has already been solved by the Apache HTTPD community, there's no reason not to integrate HTTPD into your toolkit.  
The only caveat is that, as with any network component, an additional system means one more point of attack you must consider when securing your infrastructure.

III. Installation and Configuration

As mod_jk allows communication between HTTPD and Apache, installing the module requires some legwork on both servers.  In this section of the article, we'll walk you through the whole process.  

(Note: Although not covered by this article, mod_jk is also compatible with IIS and NES/iPlanet/Sun.  Documentation for these components is available on the Tomcat Connectors project site.

Step 1 - Download the latest version of mod_jk

New versions of mod_jk are released as source packages, and as binary packages for select platforms.  Both are available for download from the Apache Tomcat Connector project download page.

Currently, the following platforms receive binary releases: AIX, FreeBSD, iSeries, Linux, Mac OS X, Netware, Solaris, and Windows (32- and 64-bit releases). 

Download the most recent release.  If you want to build mod_jk from source, follow the directions provided along with the release.

Step 2 - Install the mod_jk module

Locate the mod_jk module itself inside the release package.  If you downloaded a Unix-type release, this file will be named 'mod_jk.so'.  On a Windows system, look for 'mod_jk.dll'.

Next, you must copy this file in the the HTTPD module directory.  The location of this directory can vary from platform to platform, so if you do not know where it is located, consult the Apache HTTPD documentation.  On Unix-based systems, the module directory is usually located within the apache directory in '/usr/lib/' or '/usr/local/', while on Windows machines in can be found within the Apache directory in 'C:\Program Files'.

Step 3 - Configure httpd.conf

Now that you've installed mod_jk, you need to configure it in your httpd.conf file so that you can use it.  You can find httpd.conf in the 'conf' directory of your Apache HTTPD home folder.

The configuration provided below, based on the Tomcat documentation, is the minimum configuration required for mod_jk to run correctly.  Replace the placeholder paths with the correct paths and values for your system.

  # Load the mod_jk module.  

  LoadModule    jk_module  path/to/mod_jk.so

  # Declare the module for use with the <IfModule directive> element.  (This only applies to versions of HTTPD below 2.x.  For 2.x and above, REMOVE THIS LINE.)

  AddModule     mod_jk.c

  # Set path to workers.properties. We will create this file in the next step.  The file will be placed in the same directory as httpd.conf.

  JkWorkersFile /path/to/httpd/conf/workers.properties

  # Set path to jk shared memory.  Generally, you'll want this to point to your local state or logs directory.

  JkShmFile     /path/to/log/httpd/mod_jk.shm

  # Where to put jk logs

  # Set path to jk logs.  This path should point to the same logs directory as the HTTPD access_log.

 JkLogFile     /path/to/log/httpd/mod_jk.log

  # Set the jk log level.  Valid values for this setting are 'debug', 'error', or 'info'.

  JkLogLevel    level

  # Set timestamp log format.  Use provided variables to customize.

  JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

  # Map a worker to a namespace.  Workers represent Tomcat instances that are listening for requests.  We'll configure these in the next section.  For the sake of this example, Tomcat's "examples" context is used, and a default worker named 'worker1', which we will create in Step 4, is designated.  Multiple JkMount attributes can be used simultaneously.

  JkMount  /examples/* worker1

Step 4 - Configure workers.properties

The workers.properties file defines a list of Tomcat 'workers' to which Apache HTTPD can pass requests.  

The bare-bones configuration below defines the ajp13 worker named 'worker1' that we designated in Step 3 to handle all requests for the "examples" context:

# Define a worker named 'worker1' (more workers can be added as comma separated values)

  worker.list=worker1

  # Set worker properties

  worker.worker1.type=ajp13

  worker.worker1.host=localhost

  worker.worker1.port=8009

In the interest of simplicity, this tutorial only provides a basic configuration.  

However, the workers.properties file can become quite complex in practice, containing multiple types of workers, virtual workers, and parts of a clustering or load balancing configuration.

Although we will not cover the workers.properties file in any more depth here, full documentation is available on the Tomcat Connectors project site, and in our step to step guide to Tomcat Clustering.

Step 5 - Test Configuration

After completing the steps above, restart Apache HTTPD and navigate to the examples context.  If your configuration is correct, the page will display as normal. 

If you experience any strange errors, Apache's Tomcat Connector FAQ is a good resource to help you track down the source.

IV. Alternatives to mod_jk

Although mod_jk is the most widely used way to connect Tomcat and Apache HTTPD, other modules exist that also offer this functionality, and in some situations, may offer advantages over mod_jk.

mod_proxy_http

This module is an HTTP-specific version of the venerable mod_proxy module.  It offers most of the same features as mod_jk, but communicates over the HTTP protocol.  

Although at one time the AJP protocol offered a significant performance boost over standard HTTP, this is no longer the case, so speed is no reason to choose one over the other.  

The main reason for choosing mod_proxy_http over mod_jk is that if communication between HTTPD and Tomcat must be encrypted, mod_proxy_http may be easier to use.  This is because mod_proxy_http can be configured to use the https protocol with a minute change to its configuration, whereas encryption with mod_jk requires extra work.

On the other hand, if your application requires SSL information, this is much easier to expose with mod_jk.

mod_proxy_ajp

This module is very similar to mod_jk, except that its configuration is consistent with that of other HTTPD modules, unlike mod_jk.  Some administrators may choose to use it over mod_jk for the sake of consistency (the same can be said of mod_proxy_http).  

While mod_proxy_ajp is relatively stable, it has a few more known bugs than both mod_jk and mod_proxy_http.

There's nothing wrong with using it from a performance aspect, but also no clear advantage other than consistency.

Other Modules

A number of other modules have been created in the course of Tomcat's life that provide mod_jk-like functionality.  Many of these are now deprecated.  

While many guides still are floating around on the internet advocating the use of these modules, this is out of date information.  Using the following modules should be avoided if at all possible:

mod_webapp

mod_jserv

jk2