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.