Installing and configuring mod_jk

Intorduction
Installation of Mod_jk is not that hard but to make it work or integrate with apache and tomcat a bit tricky. I am explaining here how to install and configure apache to serve the java pages or webapps with the help of mod_jk module.

Scenario
Let me brief my scenario here, yours may be different. You can take the refference from here. I am having app1 and app2 and i want URL http://www.aap1.com to serve the pages from app1 tomcat webapp and http://www.app2.com serve the pages from app2 tomcat webapp. Also you need to take care for the tomcat port also, if you want to use two tomcat instace you you have to use the two diff ports like i am using. app1 is on 8080 port and app2 is on 8081 port.

You can install apache and tomcat via yum if you are using Redhat/CentOS distro and if you are using any Debian based system you can use apt-get/aptitude utility for the same.
I am explaining here on CentOS-5.4 disto

#yum install httpd 
#/etc/init.d/httpd restart
#chkconfig httpd on

Now its time to install mod_jk, i am using here the rpm package you can even compile it from source as well.
http://mirrors.dotsrc.org/jpackage/1.7/redhat-el-5.0/free/RPMS/
or
You can download it from centOS testing repo.

http://dev.centos.org/centos/5/testing/i386/RPMS/

#wget http://mirrors.dotsrc.org/jpackage/1.7/redhat-el-5.0/free/RPMS/mod_jk-ap20-1.2.26-1jpp.i386.rpm
or
#wget http://dev.centos.org/centos/5/testing/i386/RPMS/mod_jk-ap20-1.2.28-2.el5.centos.i386.rpm

#rpm -ivh mod_jk-ap20-1.2.26-1jpp.i386.rpm or 
#rpm -ivh  mod_jk-ap20-1.2.28-2.el5.centos.i386.rpm

Now its time to install tomcat. You can install it via yum or compile it from source. I am using the source here.

Get the tar.gz for Tomcat 5.5 — you can download it from the Apache Tomcat download site(http://tomcat.apache.org/download-55.cgi). I am using tomcat-5.5 version you can use the latest release also.

Unpack apache-tomcat-5.5.23.tar.gz under /usr/local. Rename apache-tomcat-5.5.23 to tomcat8080. Unpack the tar.gz one more time, rename it to tomcat8081.

cd /usr/local/tomcat8081/conf
- edit server.xml and change following ports:
8005 (shutdown port) -> 8006
8080 (non-SSL HTTP/1.1 connector) -> 8081
8009 (AJP 1.3 connector) -> 8010

There are other ports in server.xml, but I found that just changing the 3 ports above does the trick.

I won’t go into the details of getting the 2 Tomcat instances to run. You need to create a tomcat user, make sure you have a Java JDK or JRE installed, etc., etc.
One more thing i want to mention here, you have to set JAVA_HOME variable set to make the java application to find the exact JRE/JAVA location. If you want to set them system wide then mention that variable in /etc/profile file instead if ‘export’ on shell.

The startup/shutdown scripts for Tomcat are /usr/local/tomcat808X/bin/startup.sh|shutdown.sh.

I will assume that at this point you are able to start up the 2 Tomcat instances. The first one will listen on port 8080 and will have an AJP 1.3 connector (used by mod_jk) listening on port 8009. The second one will listen on port 8081 and will have the AJP 1.3 connector listening on port 8010.

I am assuming that you are well aware, how to deploy the tomcat apps.So i am skipping that section. Please write me at ramesh.mimit@gmail.com if you want to have a chapter on this as well.

Create Apache virtual hosts for www.myapp1.com and www.myapp2.com and tie them to the 2 Tomcat instances via mod_jk.

Here is the general mod_jk section in httpd.conf — note that it needs to be OUTSIDE of the virtual host sections:

#
# Mod_jk settings
#
# Load mod_jk module
LoadModule    jk_module  modules/mod_jk.so
# Where to find workers.properties
JkWorkersFile conf/workers.properties
# Where to put jk logs
JkLogFile     logs/mod_jk.log
# Set the jk log level [debug/error/info]
JkLogLevel    emerg
# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
# JkOptions indicate to send SSL KEY SIZE,
JkOptions     +ForwardKeySize +ForwardURICompat -ForwardDirectories
# JkRequestLogFormat set the request format
JkRequestLogFormat     "%w %V %T"

Note that the section above has an entry called JkWorkersFile, referring to a file called workers.properties, which I put in /etc/httpd/conf. This file contains information about so-called workers, which correspond to the Tomcat instances we’re running on that server. Here are the contents of my workers.properties file:

#
# This file provides minimal jk configuration properties needed to
# connect to Tomcat.
#
# The workers that jk should create and work with
#

workers.tomcat_home=/usr/local/tomcat8080
workers.java_home=/usr/lib/jvm/java
ps=/
worker.list=app1, app2

worker.app1.port=8009
worker.app1.host=localhost
worker.app1.type=ajp13
worker.app1.lbfactor=1

worker.app2.port=8010
worker.app2.host=localhost
worker.app2.type=ajp13
worker.app2.lbfactor=1

The file declares 2 workers that I named app1 and app2. The first worker corresponds to the AJP 1.3 connector running on port 8009 (which is part of the Tomcat instance running on port 8080), and the second worker corresponds to the AJP 1.3 connector running on port 8010 (which is part of the Tomcat instance running on port 8081).

The way Apache ties into Tomcat is that each of the VirtualHost sections configured for www.app1.com and www.app2.com declares a specific worker. Here is the VirtualHost section I have in httpd.conf for www.app1.com:


ServerName www.app1.com
DocumentRoot "/usr/local/tomcat8080/webapps/ROOT"

  # Options Indexes FollowSymLinks MultiViews
  Options None
  AllowOverride None
  Order allow,deny
  allow from all

ErrorLog logs/app1-error.log
CustomLog logs/app1-access.log combined
# Send ROOT app. to worker named app1
JkMount  /* app1
RewriteEngine On
RewriteRule ^/(images/.+);jsessionid=\w+$ /$1

The 2 important lines as far as the Apache/mod_jk/Tomcat configuration is concerned are:

JkMount /* app1

The line “JkMount /* app1” tells Apache to send everything to the worker app1, which then ties into the Tomcat instance on port 8080.

The line “JkUnMount /images/* app1” tells Apache to handle everything under /images itself — which was one of our goals.

At this point, you need to restart Apache, for example via ‘sudo service httpd restart’. If everything went well, you should be able to go to http://www.myapp1.com and http://www.myapp2.com and see your 2 Web applications running merrily.

You may have noticed a RewriteRule in each of the 2 VirtualHost sections in httpd.conf. What happens with many Java-based Web application is that when a user first visits a page, the application does not know yet if the user has cookies enabled or not, so the application will use a session ID mechanism fondly known as jsessionid. If the user does have cookies enabled, the application will not use jsessionid the second time a page is loaded. If cookies are not enabled, the application (Tomcat in our example) will continue generating URLs such as

http://www.myapp1.com/images/myimage.gif;jsessionid=0E45D13A0815A172BD1DC1D985793D02

In our example, we told Apache to process all URLs that start with ‘images’. But those URLs have already been polluted by Tomcat with jsessionid the very first time they were hit. As a result, Apache was trying to process them, and was failing miserably, so images didn’t get displayed the first time a user hit a page. If the user refreshed the page, images would get displayed properly (if the user had cookies enabled).

The solution I found for this issue was to use a RewriteRule that would get rid of the jsessionid in every URL that starts with ‘images’. This seemed to do the trick.

That’s about it. I hope this helps somebody

  • Francois

    I got a problem when I was doing the above setup for 64 bit OS. And Google help me out. Actually there is a bug in 64 bit rpm so that does not work. It it will give you the below error while starting the apache service.

    Starting httpd: httpd: Syntax error on line 201 of /etc/httpd/conf/httpd.conf: Cannot load /etc/httpd/modules/mod_jk.so into server: /etc/httpd/modules/mod_jk.so: undefined symbol: ap_get_server_description
    [FAILED]

    To avoid this you can compile the mod_jk from source or simple download the mod_jk from

    http://www.reverse.net/pub/apache//tomcat/tomcat-connectors/jk/binaries/linux/jk-1.2.31/x86_64/mod_jk-1.2.31-httpd-2.2.x.so here and place it under /usr/lib64/httpd/modules directory. Rename it to mod_jk.so and change the permission to 755. Thats it! You are good to go!

    Below are the steps:

    wget http://www.reverse.net/pub/apache//tomcat/tomcat-connectors/jk/binaries/linux/jk-1.2.31/x86_64/mod_jk-1.2.31-httpd-2.2.x.so
    cp mod_jk-1.2.31-httpd-2.2.x.so /usr/lib64/httpd/modules
    cd /usr/lib64/httpd/modules
    mv mod_jk-1.2.31-httpd-2.2.x.so mod_jk.so
    chmod 755 mod_jk.so
    /etc/init.d/httpd restart

  • Dinesh

    I was wondering to create mod_jk file for 64 bit.
    I got many dependency related issues while creating mod_jk file.
    Thanks so much for providing – http://www.reverse.net/pub/apache//tomcat/tomcat-connectors/jk/binaries/linux/jk-1.2.31/x86_64/mod_jk-1.2.31-httpd-2.2.x.so

    I have copied this file into my apache module directory …. & it work.

    Thanks a lot.

  • wammz

    Hi,
    I’m getting this error upon restarting apache:
    sudo /etc/init.d/httpd start
    Starting httpd: Warning: DocumentRoot [/usr/tomcat/webapps/ROOT] does not exist
    Syntax error on line 1008 of /etc/httpd/conf/httpd.conf:
    AllowOverride not allowed here

    Please note that my tomcat installation folder is /usr/tomcat

    also does my apache v/host has to be on port 80 or 8080?
    Please help,i have been working on this for some weeks now and there is no joy so far.

  • wammz

    Also,I’m using JRE and its JRE_HOME=/usr/java/latest export CATALINA_PID=/var/run/tomcat.pid

  • wammz

    Hi,

    I am getting this error after restarting apache:
    sudo /etc/init.d/httpd start
    Starting httpd: Warning: DocumentRoot [/usr/tomcat/webapps/ROOT] does not exist
    Syntax error on line 1008 of /etc/httpd/conf/httpd.conf:
    AllowOverride not allowed here

    Please note that my tomcat folder is in /usr/tomcat

    I appreciate any help.

  • Tulkras

    To answer to Dinesh & Francois, as you install your 64 bit rpm , you will find your .so in /usr/lib64/apache .

I'm happy to use Increase Sociability.