home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Apache The Definitive Guide, 3rd EditionApache: The Definitive GuideSearch this book

18.3. Connecting Tomcat to Apache

The basic document here is .../doc/tomcat-apache-howto.html. It starts with the discouraging observation:

Since the Tomcat source tree is constantly changing, the information herein may be out of date. The only definitive reference at this point is the source code.

As we have noted earlier, this may make you think that Tomcat is more suited to people who prefer the journey to the destination. You will also want to look at http://jakarta.apache.org/tomcat/tomcat-3.2-doc/uguide/tomcat_ug.html, though the two documents seem to disagree on various points.

18.3.1. mod_jk

The Tomcat interface in Apache is mod_jk. The first job is to get, compile, and install it into Apache. When we downloaded Tomcat earlier, we were getting Java, which is platform independent, and therefore the binaries would do. mod_jk is needed in source form and is distributed with the source version of Tomcat, so we went back to http://jakarta.apache.org/builds/jakarta-tomcat/release/v3.3a/src/ and downloaded jakarta-tomcat-3.3a-src.tar.gz. Things are looking up: when we first tried this, some months before, the tar files for the Tomcat binaries and sources had the same name. When you unpacked one, it obliterated the other.

Before starting, it is important that Apache has been compiled correctly, or this won't work at all. First, it must have been built using configure in the top directory, rather than src/Configure. Second, it must have shared object support enabled; that is, it should have been configured with at least one shared module enabled. An easy way to do this is to use:

./configure --enable-shared=example

Note that if you have previously configured Apache and are running a version prior to 1.3.24, you'll need to remove src/support/apxs to force a rebuild, or things will mysteriously fail. Once built, Apache should then be installed with this:

make install

Once this has been done, we can proceed.

Having unpacked the sources, we went down to the .../src directory. The documentation is in ..../jakarta-tomcat-3.3a-src/src/doc/mod_jk-howto.html.. Set the environment variable $APACHE_HOME (not $APACHE1_HOME despite the documentation) to /usr/local/apache. You also need to set JAVA_HOME as described earlier.

Descend into .../jakarta-tomcat-3.3a-src/src/native/mod_jk/apache-1.3, and execute:

./build-unix.sh

Unfortunately, this suffers from the "everything is Linux" syndrome and used weird options to the find utility. We fixed it by changing the line:

JAVA_INCLUDE="`find ${JAVA_HOME}/include -type d -printf \"-I %p \"`" ||  echo "find 
failed, edit build-unix.sh source to fix"

to:

JAVA_INCLUDE="`find ${JAVA_HOME}/include -type d | sed 's/^/-I /g'`" ||  echo "find 
failed, edit build-unix.sh source to fix"

which is substantially more portable. We also had to add this to .../jakarta-tomcat-3.3a-src/src/native/mod_jk/jk_jni_worker.c:

#ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
#endif

With these two changes, build-unix.sh worked, and we ended up with a mod_jk.so as desired.

If you are running as an appropriately permitted user, build-unix.sh will install mod_jk.so in the libexec directory of the Apache installation (/usr/local/apache/libexec by default).

The next step is to configure Apache to use mod_jk. In fact, Tomcat comes with a sample set of config files for that in .../jakarta-tomcat-3.3a/conf/jk. There are two files that need tweaking to make it work. First, mod_jk.conf:

LoadModule jk_module /usr/local/apache/libexec/mod_jk.so

<IfModule mod_jk.c>

JkWorkersFile .../jakarta-tomcat-3.3a/conf/jk/workers.properties
JkLogFile  logs/jk.log
JkLogLevel error
JkMount /*.jsp ajp12
JkMount /servlet/* ajp12
JkMount /examples/* ajp12

</IfModule>

This is pretty straightforward — we just load mod_jk in the usual way. The JkWorkersFile directive specifies the location of a file with settings for the Java components of mod_jk. JkLogFile and JkLogLevel are self-explanatory. Finally, JkMount sets the mapping from URLs to Tomcat — ajp12 refers to the protocol used to communicate with Apache. In fact, ajp13 is the more modern protocol and should be used in preference, but despite the claims of the documentation, Tomcat's default setup uses ajp12. Simply change ajp12 to ajp13 to switch protocols.

The other file that needs tweaking is workers.properties (we've removed all the comments for brevity; see the real file for copious extra information):

workers.tomcat_home=.../jakarta-tomcat-3.3a
workers.java_home=/usr/local/jdk1.1.8
ps=/
worker.list=ajp12, ajp13
worker.ajp12.port=8007
worker.ajp12.host=localhost
worker.ajp12.type=ajp12
worker.ajp12.lbfactor=1
worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
worker.ajp13.lbfactor=1
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=ajp12, ajp13
worker.inprocess.type=jni
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)tomcat.jar
worker.inprocess.cmd_line=start
worker.inprocess.jvm_lib=$(workers.java_home)$(ps)bin$(ps)javai.dll
worker.inprocess.stdout=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stdout
worker.inprocess.stderr=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stderr

The parts of this that need adjusting are workers.tomcat_home, workers.java_home, ps, and workers.inprocess.jvm_lib. The first two are self-explanatory; ps is simply the path separator for the operating system you are using (i.e., "\" for Windows and "/" for Unix). The last one, worker.inprocess.jvm_lib, should be adjusted according to OS and JVM, as commented in the sample file (but note that unless you are using the inprocess version of Tomcat, this setting won't be used — and by default, you won't be using it).

Finally, we write the actual configuration file for Apache — in this case, we decided to run it on port 8111, for no particular reason, and .../site.tomcat/conf/httpd.conf looks like this:

Port 8111
DocumentRoot .../site.tomcat/www
Include .../jakarta-tomcat-3.3a/conf/jk/mod_jk.conf

where the DocumentRoot points at some directory with HTML in it, and the Include is adjusted to point to the mod_jk.conf we altered earlier. Now all that is required is to start Tomcat and Apache in the usual way. Tomcat is started as described earlier, and Apache starts simply with:

httpd -d .../site.tomcat

You should then find that the example servlets are available. In fact, if you set the DocumentRoot to be .../jakarta-tomcat-3.3a/webapps/ROOT, then you should find that your Apache server looks exactly like your Tomcat server, only on a different port.

All that remains is to show how to add our example servlet to this configuration. Nothing could be easier. In mod_jk.conf or httpd.conf, add the line:

JkMount /simple/* ajp13

If everything is set up as we did for plain Tomcat earlier, then the Simple servlet should now work, exactly as it did for plain Tomcat. All we need is that the URL path in the JkMount matches the Context path in the apps-*.xml file.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.