There are several ways in which Tomcat can be integrated with Apache :
There are 3 connectors available at the time of this writing, and, although the documentation may say that one connector is faster than another, it really is not significant if you are using Tomcat in a low volume environment or just evaluating Tomcat for yourself. I cannot say how widely the connectors differ in terms of functionality or performance because I have not tested this out extensively.
The available connectors are :
|Connector Name||Apache version||Remarks|
|Coyote / Jk2||Apache 1.3.x / 2.x||[TBD]|
|Jk||Apache 1.3.x||The binaries, rpm and source versions can be downloaded here :
The documentation can be found here : http://jakarta.apache.org/builds/jakarta-tomcat-connectors/jk/release/v1.2.2/doc/
A full listing of connectors, their details and documentation can be found at this URL : http://jakarta.apache.org/tomcat/tomcat-4.1-doc/config/connectors.html
We will be using the following components for our integration:
|Tomcat 4.1.18||Binary tar file from http://apache.hjc.edu.sg/jakarta/tomcat-4/binaries/. This is Singapore's local mirror (very slow!)|
|Apache 1.3.27||RPM file from Red Hat, available here : http://rpmfind.net//linux/RPM/redhat/updates/7.3/i386/apache-1.3.27-2.i386.html.|
|mod_jk||If you are using Red Hat or a Red Hat-like distribution (example :
Spectra Linux), download from the Tomcat site :
If you are using United Linux (Caldera/SCO/TurboLinux/Suse/Connectiva), download from your distribution's site.
You may notice that I am using the RPM versions for both Apache and mod_jk. Most people would use the binaries or source files and compile from there. For rpm-based Linux distributions, the added complexity and possibility of error of compiling from source is not really necessary because the Apache and mod_jk RPMs seem to work fine by themselves.
An added note about the mod_jk rpm. The file includes the binaries of mod_jk along with some "standard templates" for the configuration files that mod_jk needs in order to work properly. This can be a real boon when you need to get setup quickly, but it can also be a source of considerable frustration because it differs from the write-ups I have seen on the Internet.
Important Note !
There are significant configuration differences between RPM versions for Red Hat distributions and United Linux distributions (Caldera/SCO/Suse/TurboLinux/Connectiva) for the mod_jk connector, so take care to download the correct version for your Linux distribution.
The process of getting Tomcat to talk to Apache can be divided into the following tasks :
Step 1. Install Tomcat and verify that it is working properly
Install Tomcat, then open a browser and check if you can see and execute the servlet and JSP examples bundled with it.
Step 2. Install Apache and verify that it is working properly
If you have not already installed the Apache web server, do it now. There should be no port address conflict because Apache listens on port 80 while Tomcat listens on port 8080. Verify that Apache is correctly installed by attempting to start it, then opening a browser and pointing it to http://localhost. You should see the default web server page. If you encounter any difficulties in installing or starting the Apache web server, refer to the product's website (http://httpd.apache.org/) and documentation (http://httpd.apache.org/docs/) for more information. It bears repeating that the version of Apache that I am using for this documentation is 1.3.27, and is the Red Hat rpm file.
Step 3. Shutdown both Apache and Tomcat
If both Apache and Tomcat are working fine, shutdown both of them. We are going to begin configuring them to work with each other.
Step 4. Install the mod_jk rpm file
Installing the rpm is simple. Navigate to the directory where you downloaded the file mod_jk-ap13-1.2.2-1jpp.i386.rpm and, as root, type :
# rpm -ivh mod_jk-ap13-1.2.2-1jpp.i386.rpm
Step 5. Edit the configuration files, httpd.conf, mod_jk.conf, workers.properties, server.xml
After mod_jk has been successfully installed, a set of entries will be appended to the end of Apache's configuration file, httpd.conf. Look for the following lines at the end of the file :
If the mod_jk rpm file was successfully installed, it would have copied the file mod_jk.so into the directory /etc/httpd/modules. The LoadModule and AddModule directives are to tell the Apache web server to load the module when it starts up. One thing to note here is that, in some cases, particularly when you are using Red Hat's Apache web server rpm, the AddModule command will throw an error when the httpd daemon starts up. The error says that the module is already loaded and that it will skip this directive. You may safely comment out the AddModule command, if this is the case.
Another important thing to note is the "Include" directive, which points to an external file. A lot of documentation on Tomcat-Apache integration puts the necessary directives for integration inside httpd.conf itself. The mod_jk rpm instead places integration directives in a separate external file /etc/httpd/conf/mod_jk.conf. IMHO, this is a more sensible decision.
This file is crucial to the integration, but before we go into it, we must first understand a few things about it. In mod_jk.conf we need to do the following :
At this point, it is a good idea to open up the mod_jk.conf that comes with the mod_jk rpm. We will examine each of the directives in the file, relating them to the tasks outlined above.
|JkWorkersFile||/etc/httpd/conf/workers.properties||The location of workers.properties, a file that we will examine next.|
|JkLogFile||/var/log/httpd/mod_jk.log||The location of the log file. Depending on the error level you specify, the file will contain either very verbose information or just the critical errors.|
There are 3 available options here :
Following the first 3 lines of mod_jk.conf, we encounter a series of entries that relate to SSL. We will not go into this at the moment, because we want to get a "plain-vanilla" Tomcat-Apache integration going successfully first.
What follows after the SSL section are the "contexts". We have already seen earlier that "contexts" refer to web applications that are deployed inside Tomcat. We specified a <Context> element inside Tomcat's server.xml for every web application deployed, and we have to do the same here, because Apache needs to know how to hand-off requests for web applications to Tomcat.
For every web application, we must define the contexts to Apache, and we do this by supplying the following information :
We will take, as an example, the web application and servlet we developed earlier.
|Web Application Name||MyFirst|
|URL we want to map to||http://hostname.domain.com/MyFirst/|
mod_jk Worker Name
defined inside workers.properties
How we express this as a context in mod_jk.conf is shown below :
The Location directive belongs to Apache, and is provides an access control policy based on the URL. For more information about this, click here. We may want to restrict access to the WEB-INF directory to all browsers, so we will want to append the following snippet to the bottom of the MyFirst context declaration:
That completes our configuration for mod_jk.conf. We have 2 more files to edit before we are ready to begin testing.
The Tomcat-Apache worker is analogous to a connector. The workers.properties that comes with your mod_jk rpm is very verbose and defines 2 workers, named ajp12 and ajp13, and a string of other options. The options that you may need to enable and/or change are shown below :
|workers.tomcat_home=/opt/tomcat||Set this option to point to your Tomcat installation (i.e. $CATALINA_HOME)|
|workers.java_home=/opt/IBMJava2-131||Set this option to point to $JAVA_HOME|
|ps=/||If you're using UNIX/Linux, this is correct. For Windows systems, you will need to use the backslash ("\")|
|worker.list=ajp13||The default file lists both ajp12 and ajp13. This is to provide backward compatibility, but if you're reading and following this document for the first time, you probably don't need ajp12. If you delete ajp12 here, remember to comment out all ajp12 references in the file.|
|The port number here (8009) may not be the same if you are using UnitedLinux or some earlier Red Hat rpms. Be advised that Tomcat defaults to this port number, and if you have difficulties getting your integration to work, the first place to look should be here. Ensure that the port number here and the one defined in your server.xml agree.|
|worker.ajp13.lbfactor=50||This is the load balancing factor. Default is 1, which means that less work should be done by the worker. If you have a really powerful machine, you can up this to 50 or more.|
|worker.ajp13.cachesize=10||Set this to the typical number of concurrent connections you are expecting.|
|This is a list of workers that the Load Balancer needs to manage. For more information about load balancing, please see this.|
|worker.inprocess.type=jni||This option tells the jni worker to open a JVM inside the web server process and execute Tomcat within it (in-process).|
|This option specifies the classpath to be used by the in-process JVM|
|worker.inprocess.cmd_line=start||This specifies the command line properties that are handed over to Tomcats' startup code|
|Uncomment the option that is most relevant to the JVM you are using|
|stdout is the full path to where the JVM write its System.out, while stderr is the full path to where the JVM write its System.err|
|The System properties of the JVM|
This is the last file you will need to edit, before testing the integration, so hang in there !
You will first need to comment out JMX Beans support. This will throw an error when Tomcat and Apache are started because Tomcat assumes that you are using this functionality by default. Locate the following lines and comment them out.
<!-- Comment these entries out to disable JMX MBeans support -->
Not sure how to comment them out ? Well, the commented out section above should look like the section below.
<!-- Comment these entries out to disable JMX MBeans support -->
Next we need to comment out the default non-SSL Coyote connector. Bear in mind that, unlike earlier versions of Tomcat, disabling this connector means that Tomcat is no longer directly accessible from the default "8080" port, but instead will receive all requests via Apache.
<!-- Define a non-SSL Coyote HTTP/1.1 Connector on port 8080 -->
Another section to comment out is the default Coyote/JK2 connector, because we're not using this to connect Apache with Tomcat.
<!-- Define a Coyote/JK2 AJP 1.3 Connector on port 8009 -->
Now, we need to uncomment the JK connector to enable it.
<!-- Define an AJP 1.3 Connector on port 8009 -->
And that's it! Save the file, shutdown Tomcat and Apache, if both are currently running and we're ready to test.
|Important Note ! If you wish to use the admin and manager web applications in Tomcat, you WILL need MBeans support. This means that you should leave the MBeans listeners uncommented, and use the Coyote/JK2 AJP1.3 Connector on port 8009 section, instead of the AJP 1.3 Connector section.|
Step 6. Start Tomcat
The startup sequence, after you have configured Tomcat to communicate with Apache is always to start Tomcat first. If you're running Tomcat on a system that has a slow processor or not enough RAM, you will find that Tomcat starts rather slowly. To check on the progress of the startup, do a 'tail -f $CATALINA_HOME/logs/catalina.out' and see the messages.
Step 7. Start Apache
Once Tomcat has started up, you can start Apache.
Step 8. Verify that everything works
Open a browser and key in the URL. For our web application 'MyFirst', the URL to key in for the HelloWorld servlet would be "http://localhost/MyFirst/HelloWorld". If you get an error, check to see if you followed the instructions closely. Another thing to check are the error logs.
One common source of error is the JK port. If you get an error that says that Apache is unable to communicate with Tomcat, check the port address in your workers.properties and compare it with the one defined in server.xml. They should be the same. If not, just change the values so both agree.
If everything works, congratulations ! You have successfully integrated Apache and Tomcat !