MOD_JK Installation and Configuration - Apache HTTPD and Tomcat

Apache and Tomcat are the A and B of middleware that everyone learns and they have widely used web server and application server across the world( sometimes referred to as just web container as it does have no EJB)

It's like a sandbox for every rookie to learn things and manipulate them later wherever it may require

If you are not very well aware of mod_jk and AJP protocol, go and search in google you will get numerous links.

This article's main objective is to cover the apache and tomcat integration using mod_jk practically. therefore I have not gone any deep into apache HTTP server (or) tomcat either.

This article presumes that you have the Linux machine with the Apache2.4+ installed

Let's go

Step1: Make sure the apache services are running

apachectl status

Start the service ( if not already)

apachectl start


Step2: Install Dependencies

Before Installing  Mod_JK, there are few dependencies you have to install

yum install httpd-devel ( source of apxs )
yum install gcc libtool


Step3: Download mod_jk connector (tar.gz format) from tomcat website

You will get some downloadable link like shown below.

you can optionally use wget utilty to download the tar ball directory to your server by placing the mirror link

Once you got the tar.gz file in the server at any temp location, untar it using tar -xvf

tar -xvf tomcat-connectors-1.2.42-src.tar.gz

After untar, go to the untarred directory and then to the native directory



Step4:  Configure with APXS

Run the following command in the same native directory

./configure -with-apxs=/usr/bin/apxs
root@mw-web01# ./configure -with-apxs=/usr/bin/apxs
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes

Note*: Sometimes apxs could be found in /usr/sbin also, Please use locate apxs (or) find / -name "apxs" commands to find the location of apxs and use the respective path with configure command

Step5:  Execute the Make Command

Execute the make command to build the .so (system object) file on the same native directory

root@mw-web01# make
Making all in common
make[1]: Entering directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/common'
/usr/lib64/apr-1/build/libtool – silent – mode=compile gcc -std=gnu99 -I. -I/usr/include/httpd -DHAVE_CONFIG_H -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong – param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -pthread -DHAVE_APR -I/usr/include/apr-1 -I/usr/include/apr-1 -DHAVE_CONFIG_H -DLINUX -D_REENTRANT -D_GNU_SOURCE -c jk_ajp12_worker.c -o jk_ajp12_worker.lo
/usr/lib64/apr-1/build/libtool – silent – mode=compile gcc -std=gnu99 -I. -I/usr/include/httpd -DHAVE
make[1]: Leaving directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/apache-2.0'
make[1]: Entering directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native'
make[1]: Nothing to be done for `all-am'.
make[1]: Leaving directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native'
target="all"; \
list='common apache-2.0'; \
for i in $list; do \
  echo "Making $target in $i"; \
  if test "$i" != "."; then \
  (cd $i && make $target) || exit 1; \
  fi; \
Making all in common
make[1]: Entering directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/common'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/common'
Making all in apache-2.0
make[1]: Entering directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/apache-2.0'
../scripts/build/ SH_LIBTOOL='/usr/lib64/apr-1/build/libtool – silent' `pwd`
/usr/lib64/apr-1/build/libtool – silent – mode=install cp /etc/httpd/modules/tomcat-connectors-1.2.42-src/native/apache-2.0/
libtool: install: warning: remember to run `libtool – finish /usr/lib64/httpd/modules'
make[1]: Leaving directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/apache-2.0'

Now you should be able to see the apache2.0 directory created under the native directory,

Step6:  Copy the Generated file to apache modules

If you list the content of the directory you could see the file created, copy it to modules directory of your apache web server

root@ mw-web01 # pwd
root@ mw-web01 # ls -rlt
total 4960
-rw-r--r – 1 root bin 1335 Sep 13 2010 config.m4
-rw-r--r – 1 root bin 11019 Nov 14 2011 mod_jk.dsp
-rw-r--r – 1 root bin 6351 Nov 16 2011 NWGNUmakefile
-rw-r--r – 1 root bin 9541 Nov 16 2011 bldjk.qclsrc
-rw-r--r – 1 root bin 10350 Nov 16 2011 bldjk54.qclsrc
-rw-r--r – 1 root bin 6947 Mar 9 2012
-rw-r--r – 1 root bin 1434 Dec 20 2014
-rw-r--r – 1 root bin 3068 Dec 20 2014
-rw-r--r – 1 root bin 147853 Sep 22 2016 mod_jk.c
-rw-r--r – 1 root root 3328 Nov 6 14:37 Makefile
-rw-r--r – 1 root root 1622 Nov 6 14:37 Makefile.apxs
-rw-r--r – 1 root root 365288 Nov 6 14:49 mod_jk.o
-rw-r--r – 1 root root 270 Nov 6 14:49 mod_jk.lo
-rwxr-xr-x 1 root root 1553336 Nov 6 14:49
-rw-r--r – 1 root root 920 Nov 6 14:49
-rw-r--r – 1 root root 2917994 Nov 6 14:49 mod_jk.a

In my case its /etc/httpd/modules

cp /etc/httpd/modules

here is my directory listing of server_root /etc/httpd for your reference

root@ mw-web01 # ls -rlt
total 4
drwxr-xr-x. 2 root root 78 Oct 31 13:58 conf.d
drwxr-xr-x. 2 root root 4096 Oct 31 13:58 conf.modules.d
lrwxrwxrwx 1 root root 19 Oct 31 13:58 logs -> ../../var/log/httpd
lrwxrwxrwx 1 root root 29 Oct 31 13:58 modules -> ../../usr/lib64/httpd/modules
lrwxrwxrwx 1 root root 10 Oct 31 13:58 run -> /run/httpd
drwxr-xr-x. 2 root root 35 Nov 6 14:55 conf


Step7: Load the Module

Now it is a time to load the module .SO file, we have just copied to the  modules directory

In an earlier version of apache if we want to Load any module we would use LoadModule directive in httpd.conf file.

But, in Apache2+ every configuration files are in a distinct directory and imported into httpd.conf using Include directive.

You can see there are multiple INCLUDES in httpd.conf

root@ mw-web01 # grep -i ^Include conf/httpd.conf
Include conf.modules.d/*.conf
Include sites-enabled/*
IncludeOptional conf.d/*.conf

and all the module related configurations are loaded from conf.modules.d directory

our LoadModule has to be put under /etc/httpd/conf.modules.d directory as a new file. This setup would help in categorizing and managing the modules effectively

here is the Snap of my conf.modules.d directory before adding a new file.

root@ mw-web01 # cd conf.modules.d
root@ mw-web01 # pwd
root@ mw-web01 # ls -rlt
total 32
-rw-r--r--. 1 root root 43 Aug 19 2014 10-wsgi.conf
-rw-r--r – 1 root root 451 Jul 26 04:43 01-cgi.conf
-rw-r--r – 1 root root 88 Jul 26 04:43 00-systemd.conf
-rw-r--r – 1 root root 957 Jul 26 04:43 00-proxy.conf
-rw-r--r – 1 root root 742 Jul 26 04:43 00-mpm.conf
-rw-r--r – 1 root root 41 Jul 26 04:43 00-lua.conf
-rw-r--r – 1 root root 139 Jul 26 04:43 00-dav.conf
-rw-r--r – 1 root root 3739 Jul 26 04:43 00-base.conf
root@ mw-web01 #

Now we need to Create a new file named mod_jk.conf and add the following lines

LoadModule jk_module "/etc/httpd/modules/"

JkWorkersFile /etc/httpd/conf/
JkLogFile /etc/httpd/logs/mod_jk.log

JkLogLevel info

JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkRequestLogFormat "%w %V %T"


JkWorkersFile is the file where we would be defining the application server details and nodes etc
JkLogFile is the log for the mod_jk, It is good to troubleshoot in case of issues

The other four directive's tasks could be easily interpreted by their very name


Step8: Creating Workers ( they are our minions!!)

We have defined theJkWorkersFile file name and location on the Step7 inside the mod_jk.conf file

Now Its a time to create a Workers file and define the application server (tomcat) details,  In my case I have tomcat servers running at following hostnames and ports

Here 8009 is the AJP port number on the backend Tomcat Servers.

#Define the list of workers you have


# HERE is where you decide on how many Tomcat Server's there are in the cluster

# Set Worker

mwitc-node1  is the worker name (member) here, there will be a dedicated worker for each application server node. Name of this worker should be matched to the JVM_Route parameter value in the back-end tomcat's server.xml file


Step8: Adding JVMRoute in server.xml

in the backend servers you need to add a jvmRoute parameter and the value of jvmRoute should be as same as the worker name mentioned in the file.

Hostname WorkerName JvmRoute Value tc-node1 tc-node1 tc-node2 tc-node2
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tc-node1">


Step9: Update your Apache Virtual Host file and add JKMount

Update your virtual Host Configuration to enable URI forwarding

Now go back to your virtual host configuration file on the Apache webserver end based on your apache server configuration you can find the file in any of these paths


Now, it's time to configure apache to forward the requests to the application server

If the URI path aka context-root matches to a certain string. These Strings are basically referred to as Context-root (or) war file names in the tomcat end.

At the end of your virtual host file, add the below line

JkMount /<Your Application Name>/* lb_router
JkMount /myapp/* lb_router


JKMount instructs, this should be handled by mod_jk

Here myapp refers to the application  war file name (or) the context root

lb_router worker name referring to the file

What we basically do here is, mapping the worker to th URI or Context Root. More like Location in Virtual Host configuration

Now we are all set to test the route.

Test your application now with the web server name

http://<virtualhost name>/<contextroot>

In my case it is

Step9 : Validate the Logs - Audit the Logs

Time to AUDIT the Logs


tail -20f /etc/httpd/mod_jk.log

[Mon Nov 06 16:50:16 2017]lb_router 0.002238
[Mon Nov 06 16:55:28 2017][24044:139753907869824] [info] init_jk::mod_jk.c (3595): mod_jk/1.2.42 initialized
[Mon Nov 06 16:55:28 2017][24044:139753907869824] [info] init_jk::mod_jk.c (3595): mod_jk/1.2.42 initialized
[Mon Nov 06 16:55:46 2017]lb_router 0.002961
[Mon Nov 06 16:55:46 2017]lb_router 0.013606
[Mon Nov 06 16:55:49 2017]lb_router 0.005105

Hope this article helps.


Sarav AK

Follow me on Linkedin My Profile
Follow DevopsJunction onFacebook orTwitter
For more practical videos and tutorials. Subscribe to our channel

Buy Me a Coffee at

Signup for Exclusive "Subscriber-only" Content