Last week I gave a presentation to the CFMeetup group showing how I use Eclipse and Tomcat to develop CFML applications across any of the current CFML engines (if you missed it and are interested, here is the link to the meeting recording). One of the aspects of my environment that we didn’t have time to discuss is the link between the Apache web server and Tomcat. Some people will accurately point out that you don’t really need the Apache web server since Tomcat has a very fast built-in server that you can easily configure to run on port 80 rather than the default 8080. I personally like to try to keep things as close to production configurations as possible so I use the Apache web server when developing locally.

There are a few different methods for sending requests over to Tomcat from Apache. The one that I’ve found most useful uses the Apache module named mod_jk.so. There are 3 steps required to get mod_jk working between Apache and Tomcat:

  1. Install and enable the module in the main Apache configuration file
  2. Create a properties file that tells the module about your Tomcat installation
  3. Modify your host (or virtual host) configuration to tell Apache what kinds of requests should be sent to Tomcat

Installing and enabling the mod_jk module
The first thing that you have to have is the mod_jk.so file located in a place where Apache can find it. Download the pre-built binary for your particular operating system and put it in the folder that contains the other modules for Apache (in my case, on OS X, this folder was /usr/libexec/apache2).

Once the file is in place, you’ll need to edit the Apache config files to tell it how to find and interact with the module. You can put this information in your main config file if you want. Since that main config file tends to be very long anyway, I’ve chosen to put all the mod_jk related configuration in a separate file. I named the file “tomcat.conf” saved in the same folder as the main Apache config file but you can name it whatever makes sense to you. Here are the contents of my tomcat.conf file (change the file system paths as needed for your own setup):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Load mod_jk module
LoadModule    jk_module  /usr/libexec/apache2/mod_jk.so
 
# Where to find workers.properties
JkWorkersFile /usr/local/apache2/conf/workers.properties
 
# Where to put jk shared memory
JkShmFile     /var/log/httpd/mod_jk.shm
 
# Where to put jk logs
JkLogFile     /var/log/httpd/mod_jk.log
 
# Set the jk log level [debug/error/info]
JkLogLevel    info
 
# Select the timestamp log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
 
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories -ForwardLocalAddress

This config file tells Apache to load the mod_jk.so module, load the workers.properties file to configure it and then sets some options for how the module will operate. The last line contains some options that are used in URL rewriting that I found on a blog at some point. Since this is a development environment, I’m not sure they’re necessary, but like they say, if it isn’t broken……

Once that is saved, I use the following statement to include this file into my main Apache config file (this is the last statement in my httpd.conf file):

1
2
#Tomcat config
Include conf/tomcat.conf

Configuring the module’s properties
You’ll notice the second directive in my tomcat.conf file mentions loading the contents of a workers.properties file. This file contains the information that the module needs to connect to one or more Tomcat server instances. Below is part of the contents of my workers.properties file (with some items made generic):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Define workers using ajp13
worker.list=server1site1,server2site1,server2site2,server2site3
 
# ----- Server 1 sites -----
worker.server1site1.type=ajp13
worker.server1site1.host=site1.local
worker.server1site1.port=8009
 
# ----- Server 2 sites -----
worker.server2site1.type=ajp13
worker.server2site1.host=site2.local
worker.server2site1.port=8010
 
worker.server2site2.type=ajp13
worker.server2site2.host=site3.local
worker.server2site2.port=8010
 
worker.server2site3.type=ajp13
worker.server2site3.host=site4.local
worker.server2site3.port=8010

This file supports a configuration with 2 different servers set up in Eclipse with different TCP numbers (server1 uses the default Tomcat ports). The server2 config has 3 hosts configured in the server.xml file for that server. The “.host” portion of each configuration matches the entry in each host entry of Tomcat’s server.xml file.

Configure your Apache virtual host
The last step is to configure your Apache virtual host with which types of requests to send through the mod_jk module to Tomcat. I’ve added this entry to my VirtualHost file for the selected vhost:

1
2
JkMount /*.cfm server1site1
JkMount /*.cfc server1site1

These lines tell Apache to send any requests for cfm or cfc files to the Tomcat instance defined in the worker.properties file as “server1site1”.

Once you’ve got all this in place, you need to restart your Apache server and you should be able to hit your site on the regular port 80 using the URL you set up in your VirtualHost configuration and have the CFML engine running on Tomcat process the CFML code.

2 thoughts on “Followup to my CFMeetup development environment presentation

  1. Jeff Chastain

    Dan – The CFUG presentation was great. I have been back over it a couple of times and still have some question as to how you have deployed the various CF engines to Tomcat. Have you by chance described that setup process on your blog or anywhere else?

    Thanks.
    — Jeff

  2. @Jeff Chastain Hey Jeff, I don’t think I’ve got that part in writing anywhere. I keep a folder of “exploded” WAR files off to the side that I use to drop the appropriate engine’s WEB-INF (and other folders) into my web root when I set up a new project. The easiest way I’ve found to do it is to start Tomcat manually, then copy in the WAR file for a particular engine and let Tomcat auto deploy it. Once it’s finished, stop Tomcat and copy the contents of the exploded WAR out and save it somewhere for use later so you don’t have to go through that exercise every time you spool up a new site. You wind up with an entire copy of the engine in each web site, but that’s the way I prefer it to make sure all settings stay separate between client sites in development. Feel free to give me a shout if you need anything.

Leave a Reply

Your email address will not be published. Required fields are marked *

*