When integrating Apache Tomcat with Apache httpd using mod_jk, many developers encounter the frustrating "404 Not Found" error despite following official documentation. The core issue often lies in configuration nuances between virtual hosts and URI mapping.
First, verify these essential elements in your setup:
# In httpd.conf or apache2.conf
LoadModule jk_module modules/mod_jk.so
JkWorkersFile /etc/apache2/workers.properties
JkLogFile /var/log/apache2/mod_jk.log
JkLogLevel debug
JkMount /webapp/* worker1
The workers.properties file should contain:
worker.list=worker1
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009
A common oversight is forgetting that JkMount directives don't automatically apply to VirtualHosts. The solution is to either:
# Option 1: Copy global mounts to VirtualHosts
JkMountCopy On
# Option 2: Explicitly declare within each VirtualHost
JkMount /webapp/* worker1
# Other VirtualHost directives
Ensure your web application's context path matches the JkMount path. For example, if your WAR is deployed as myapp.war
, the proper configuration would be:
# Apache config
JkMount /myapp/* worker1
# Tomcat's server.xml
When encountering "missing uri map" errors in mod_jk.log, check:
- Apache error.log for configuration errors
- Tomcat's catalina.out for AJP connection attempts
- Network connectivity between httpd and Tomcat (telnet localhost 8009)
Here's a verified configuration for Debian systems:
# /etc/apache2/mods-available/jk.conf
JkWorkersFile /etc/apache2/workers.properties
JkLogFile /var/log/apache2/mod_jk.log
JkLogLevel info
JkMountCopy On
JkMount /tomcat7* worker1
# /etc/tomcat7/server.xml (relevant portion)
Remember to enable the configurations with:
a2enmod jk
systemctl restart apache2
systemctl restart tomcat7
When integrating Tomcat with Apache HTTP Server through AJP (Apache JServ Protocol), the configuration involves multiple components working in harmony. Let's break down the essential elements:
# Essential mod_jk configuration in httpd.conf
LoadModule jk_module modules/mod_jk.so
JkWorkersFile /etc/apache2/workers.properties
JkShmFile /var/log/apache2/mod_jk.shm
JkLogFile /var/log/apache2/mod_jk.log
JkLogLevel debug
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkMount /webapp/* ajp13_worker
The workers.properties file serves as the bridge between Apache and Tomcat. A properly configured file should resemble:
# Define worker list
worker.list=ajp13_worker
# Set properties for AJP13 worker
worker.ajp13_worker.type=ajp13
worker.ajp13_worker.host=localhost
worker.ajp13_worker.port=8009
worker.ajp13_worker.connection_pool_size=50
worker.ajp13_worker.connect_timeout=5000
worker.ajp13_worker.prepost_timeout=10000
The most common pitfall occurs when VirtualHost configurations don't properly inherit JkMount directives. Here's a robust VirtualHost setup:
ServerName example.com
JkMountCopy On
JkMount /webapp* ajp13_worker
# Optional: Static content handling
Alias /static /path/to/static/files
Require all granted
When facing "missing uri map" errors, consider these diagnostic steps:
- Verify mod_jk is properly loaded in Apache:
apachectl -M | grep jk
- Check Tomcat's AJP connector is enabled in server.xml:
- Test the AJP connection directly:
telnet localhost 8009
For production environments, consider these optimizations:
# In workers.properties
worker.ajp13_worker.socket_keepalive=true
worker.ajp13_worker.retries=3
worker.ajp13_worker.reply_timeout=300000
# In httpd.conf
JkOptions +ForwardURICompatUnparsed
JkOptions +ForwardDirectories
Always secure your AJP connection, especially in production: