I was talking to a friend who asked about configuring an Apache virtual host to use Tomcat. I have Apache httpd 2.2.8 running on port 80 and tomcat 5.5.26 running on port 8080 on Windows XP Pro. So the following worked for me:
http://server/ <– handled by Apache
http://server:8080/ <– handled by Tomcat
At first, I didn’t quite understand what he was saying. I thought he wanted something like this:
http://server/ <– to be handled by Apache
http://server/tomcat/ <– to be handled by Tomcat
http://server/any/other/path <– to be handled by Apache
He said he didn’t care about the port 8080 being displayed, so could just use mod_rewrite?
Here’s the rule I came up with, and added to httpd.conf:
RewriteEngine On
RewriteRule ^/tomcat/(.*) http://server:8080/$1
So whenever somone types the following url http://server/tomcat/foo they get a rewritten URL displayed as http://server:8080/foo handled by tomcat. They can continue to navigate relative URLs as long as they stay within the http://server:8080/ domain. Any URL with http://server/ (without port 8080 in the URL) will still be handled by Apache. So will any URLs starting with http://server:80/
This is the simplest possible solution.
I then found out that what he actually wanted was to use one server (OS) to host two domains, one using Apache and the other Tomcat. This was easy enough to solve by creating two virtual hosts, one for each server.
http://apache/ <– handled by Apache
http://tomcat/ <– handled by Tomcat
First, I needed to create the hosts. He was using a registered domain, but I just both to my /etc/hosts file (actually C:\WINDOWS\System32\drivers\etc\hosts):
127.0.0.1 localhost apache tomcat
Do whatever you need to do to make it resolve.
First I created two Apache config files, one for each virtual host. I added the rewrite rule to only the tomcat vhost.
C:/apache/conf/vhosts/apache.conf
<VirtualHost 127.0.0.1:*>
ServerName apache
DocumentRoot “C:/Apache/htdocs”
<Directory />
Options All
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
C:/apache/conf/vhosts/tomcat.conf
<VirtualHost 127.0.0.1:*>
ServerName tomcat
DocumentRoot “C:/Apache/htdocs”
RewriteEngine On
RewriteRule ^/(.*) http://apache:8080/$1
<Directory />
Options All
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
I added the following to my httpd.conf, so that they would be included.
include “C:/Apache/httpd/2.2/conf/vhosts/*.conf”
Also make sure you have the following in httpd.conf to handle virtual hosts on the correct IP
NameVirtualHost 127.0.0.1:*
and that mod_rewrite is enabled.
I restarted Apache and everything was working. Requests to http://apache/ get handled by Apache,

and requests to http://tomcat/ get rewritten to http://tomcat:8080/ and then handled by Tomcat.

I then created exceptions to the rules, so that requests to http://tomcat/exception/* are handled by Apache and requests to http://apache/tomcat/* are handled by Tomcat.
I added the following to apache.conf:
RewriteEngine On
RewriteRule ^/tomcat/(.*) http://apache:8080/$1

and added to tomcat.conf (placed before the other RewriteRule):
RewriteRule ^/exception – [L]

This is simple enough. But what if we didn’t want the port number displayed? (Or any other rewrite confusion?)
Apache httpd server is commonly used as a proxy in front of tomcat or other servers. My friend said he’d heard about a module that handles this. There are in fact several approaches, some of which are out of date.
The original (to my knowledge) was mod_jserv. This is out of date. For a while, the two common methods (that I know of) were mod_jk and mod_proxy. The first ended up being faster because it used a binary protocol, AJP (Apache JServ Protocol), but was more difficult to configure. Another module, mod_jk2 was create with the goal of making that easier. This has since been deprecated in favor of the original mod_jk (currently at version 1.2.6). A newer module that is available, only for Apache 2.2 is mod_proxy_ajp. It uses a proxy, but also uses the AJP binary protocol, so is faster, and keeps open connections between Apache and tomcat. This would possibly be the best of both worlds, but is newer, and is doesn’t have some of the advanced features that mod_jk has. Load balancing and https are two issues that apparently mod_jk handles better than mod_proxy. It also has some additional management and error reporting. Also, I think large request sizes (more than 8k) can be handled by mod_jk (but only up to 64k), but not mod_proxy_ajp . This may have been fixed already.
Here are some links:
http://tomcat.apache.org/connectors-doc/
http://httpd.apache.org/docs/2.2/mod/mod_proxy_ajp.html
http://directwebremoting.org/blog/joe/2006/02/01/mod_jk_is_dead_long_live_mod_proxy_ajp.html
http://blogs.jboss.com/blog/mturk/2007/07/16/Comparing_mod_proxy_and_mod_jk.txt
http://www.mail-archive.com/users@tomcat.apache.org/msg03570.html
http://anilsaldhana.blogspot.com/2006/04/modjk-versus-modproxy.html
http://confluence.atlassian.com/display/DOC/Running+Confluence+behind+Apache
Here’s how I set it up to work on my localhost.
I created the following hosts:
127.0.0.1 localhost apache tomcat modjk modproxyajp
(okay, I actually set up apache.ae tomcat.ae modjk.ae modproxyajp.ae, but deleted the ‘.ae’ from this example for clarity.)
I downloaded mod_jk from here. The latest version is for Apache 2.2.4, but I haven’t seen a problem. I renamed it to mod_jk.so and copied it to my Apache modules directory.
C:\Apache\modules\mod_jk.so
Then I added to following to my httpd.conf (so that I can reference mod_jk outside the vhost):
LoadModule jk_module modules/mod_jk.so
JkWorkersFile “C:/Apache/conf/workers.properties”
JkLogFile “C:/Apache/logs/mod_jk.log”
JkLogLevel info
JkOptions +ForwardURICompatUnparsed
Next I created the workers.properties file referred to in my httpd.conf:
C:/Apache/conf/workers.properties
worker.list=worker1
worker.worker1.host=localhost
worker.worker1.port=8009
worker.worker1.type=ajp13
I then set up a vhost for modjk:
C:/Apache/conf/vhosts/modjk.conf
<VirtualHost 127.0.0.1:*>
ServerName modjk
DocumentRoot “C:/Tomcat/webapps/”
JkMount /* worker1
</VirtualHost>
The JKMount directive says that every URL (/*) is handled by the jk worker1. You can create multiple workers and specify then in your tomcat server.xml config file. This is included by default in mine:
<Connector port=”8009″ enableLookups=”false” redirectPort=”8443″ protocol=”AJP/1.3″ />
After restarting Apache, now, when I go to http://modjk I get the Tomcat homepage:

I also added the following to my original apache.conf so that I can reference mod_jk from a certain directory:
C:/Apache/conf/vhosts/apache.conf
<VirtualHost 127.0.0.1:*>
ServerName apache
DocumentRoot “C:/Apache/htdocs”
RewriteEngine On
RewriteRule ^/tomcat/(.*) http://apache:8080/$1
<Directory />
Options All
Order deny,allow
Allow from all
</Directory>
JkMount /modjk/* worker1
</VirtualHost>
When I go to http://apache/modjk/ it uses Tomcat, but I get a 404, because my path is messed up. I either need to specify the document root for the <Location /modjk> or have Tomcat expect this path.

TODO: fix this.
Then I tried out mod_proxy_ajp. It’s already included with Apache 2.2, so I didn’t need to download anything. I created the following vhost config file:
C:/Apache/conf/vhosts/modproxyajp.conf
<VirtualHost 127.0.0.1:*>
ServerName modproxyajp
DocumentRoot “C:/tomcat/webapps/”
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/
<Location />
Order allow,deny
Allow from all
</Location>
</VirtualHost>
Notice the ProxyPass, which is kind of like a rewrite, but it also specifies the ajp:// protocol. If Tomcat were on a different server than Apache, you’d specify the hostname instead of localhost. Port 8009 is the default, and you’ll remember that it’s set for the tomcat connector in server.xml
Now I can restart Apache and go to http://modproxyajp/ and it serves Tomcat (which is actually running on port 8080) through Apache (on port 80), using the AJP binary protocol from mod_jk, but via the built-in AJP proxy.

I also edited my original apache.conf to be able to server mod_proxy_ajp from that host as well.
<VirtualHost 127.0.0.1:*>
ServerName apache
DocumentRoot “C:/Apache/htdocs”
<Directory />
Options All
Order deny,allow
Allow from all
</Directory>
# use mod_rewrite to forward directly to tomcat on port 8080
RewriteEngine On
RewriteRule ^/tomcat/(.*) http://apache:8080/$1
# use mod_jk to forward to tomcat
JkMount /modjk/* worker1
# use mod_proxy_ajp to forward to tomcat
ProxyPass /modproxyajp ajp://localhost:8009/
ProxyPassReverse /modproxyajp ajp://localhost:8009/
</VirtualHost>
I restarted Apache once again and typed http://apache/modproxyajp/ into my browser.

I don’t know whether mod_jk or mod_proxy_ajp is better. My guess is it depends on your definition of “better.” Mod_jk has the advantage of being older, and Mod_proxy_ajp has the advantage of being built in. For simple uses, either appear fine.
I haven’t got into any details about load balancing or complex management or session issues because I don’t know enough about it yet. If there’s a demand, I might post a follow up.
Like this:
Like Loading...