Configuring Tomcat and Apache With JK 1.2
Pages: 1, 2
Now that Tomcat is configured to listen to port 8009 for incoming AJP13 request, let's tell Apache to actually talk to Tomcat using that port and protocol. This process, while not terribly complicated, is somewhat more complicated than Tomcat's equivalent configuration, so I have broken it down into several sections.
Create a Tomcat Worker
We begin the Apache configuration by creating a Tomcat worker definition that will tell Apache how and when to talk to Tomcat. This is done by creating a Tomcat worker file, containing the definition for at least one Tomcat worker. A Tomcat worker is a process that defines a communications link between Apache and a Tomcat container. (If you have any questions about Tomcat Workers, you can refer to the actual Jakarta documentation.) We will cover Tomcat workers in much more detail when we get to Part 5 of this series, "Advanced Connector Configurations."
The Tomcat worker file, in this example, should be named
workers.properties and should be copied into the <CATALINA_HOME>/conf directory of the Tomcat instance that you will be integrating with Apache. (<CATALINA_HOME> represents the base directory of your Tomcat installation.)
Now add the following properties to this newly-created file and save your changes.
worker.list=testWorker worker.testWorker.port=8009 worker.testWorker.host=localhost worker.testWorker.type=ajp13
These entries define a Tomcat worker named
testWorker that resides on the same host as the Apache server,
localhost, and listens to port 8009 for a client using the AJP13 protocol. This is accomplished using a series of worker properties.
The first of these properties is the
worker.list property. This property defines a list of Tomcat workers to which our instance of Apache will talk. This list can define any number of Tomcat workers as long as each name is separated with a comma.
(Note that all of the worker properties are prepended by the string
worker. This string acts the top-level identifier of all worker properties.)
In our example we are defining a single worker named
testWorker. Once we have a worker named, we can then modify the attributes of that worker explicitly using the following syntax:
worker.testWorker + name of property being modified
Because our current example is so simple, we are only going to modify three of the new workers properties:
type. All of these are easy enough to decipher, but for clarity's sake, they are still described in the following table.
||The port property defines the port number of this Tomcat worker. This value must match the port attribute of the previously defined Tomcat
||The host property defines the hostname of this Tomcat worker. Because we are configuring both Apache and Tomcat on the same host, this value is currently set to localhost.|
||The type property defines the protocol of this Tomcat worker, which in our case is
httpd.conf Configuration File
Now that we have defined a Tomcat worker, we need to tell Apache to talk to that worker. We do this by making several modifications to Apache's <APACHE_HOME>/conf/httpd.conf file. This process is broken down into several steps:
Copy the previously downloaded
mod_jkmodule to the <APACHE_HOME>/libexec directory.
Tell Apache to load the
mod_jkmodule. We do this by adding the
AddModuledirectives to the bottom of the httpd.conf file, as follows:
LoadModule jk_module libexec/mod_jk-1.3.26.dll AddModule mod_jk.c
Note: If your OS is a flavor of Unix, then you will most likely be pointing at the file mod_jk-1.3-eapi.so. If you are on a Windows box, which is what I am currently using, then you will most likely be pointing to the file mod_jk-1.3.26.dll.
We must now tell
mod_jkthe location of our workers.properties file. This is done by using the
JkWorkersFileproperty. Make sure you use the appropriate path when defining the location of your properties file.
Our next step is an optional but very useful (when you run into problems) step: naming a log file that will record
mod_jk's actions. You do this by adding two additional properties to the httpd.conf file. The first of these properties,
JkLogFile, identifies the location of the log file. The second,
JkLogLevel, defines the logging level, which can be one of three logging levels:
info, which decrease in level of verbosity, respectively.
Note: If you do not define a log level, then no log file will be generated.
JkLogFile C:/Tomcat4_1_12/logs/mod_jk.log JkLogLevel debug
The next step is to tell Apache that we want all static content requested from the /examples directory to be served from the <CATALINA_HOME>/webapps/examples directory. This is accomplished using the
Aliasdirective, as follows:
Alias /examples C:/Tomcat4_1_12/webapps/examples
We now need to tell Apache that we want all requests with the patterns
/examples/*.jspto be rerouted and serviced by the worker named
testWorker. This is accomplished using the
JkMountdirective, as follows.
JkMount /examples/servlet/* testWorker JkMount /examples/*.jsp testWorker
The final step in our Apache/Tomcat integration is a step that restricts all requests to the
/exampleapplication's WEB-INF directory. This is done by telling Apache that it should deny all requests to the /examples/WEB-INF directory. The following
<Location>element enforces this constraint:
<location "/examples/web-inf/"> AllowOverride None deny from all </location>
When all of these changes are made, you should have an addition similar to the following, with appropriate path changes, at the bottom of Apache's httpd.conf file.
LoadModule jk_module libexec/mod_jk-1.3.26.dll AddModule mod_jk.c JkWorkersFile C:/Tomcat4_1_12/conf/workers.properties JkLogFile C:/Tomcat4_1_12/logs/mod_jk.log JkLogLevel debug Alias /examples C:/Tomcat4_1_12/webapps/examples JkMount /examples/servlet/* testWorker JkMount /examples/*.jsp testWorker <Location "/examples/WEB-INF/"> AllowOverride None deny from all </Location>
What Have We Done?
As I mentioned in the previous section, the
mod_jk modules act like conduits between a Web server (Apache, for our purposes) and Tomcat. In the last two sections, we basically installed and configured this conduit. Now Apache performs in the following manner:
On Apache Startup:
- Apache loads the
- It then tells the
mod_jkmodule that all of its workers are defined in the worker.properties file, which in our case defines a single worker,
- Apache then associates all requests for the patterns
/example/*.jspwith the worker
When a request, including either of the patterns
/example/*.jsp, is received:
- Apache will turn the request over to the
mod_jkwill then pass the request to the Tomcat Connector
org.apache.ajp.tomcat4.Ajp13Connector, which is listening on port 8009.
- This Connector then takes over and services the request as if it were running inside the Tomcat container.
- When the request has been serviced, the
org.apache.ajp.tomcat4.Ajp13Connectorwill return the results back to the
mod_jkmodule and control will be shifted back to Apache.
Testing Your New Configuration
At this point, you can now test your changes. To do this you must first start Tomcat and then start the Apache server. When both servers are up and running, open your browser to either http://localhost/examples/servlets/index.html or http://localhost/examples/jsp/index.html and browse around, testing your new integration.
That about does it for a basic Apache/Tomcat configuration. Do note that all requests to the /examples application are no longer using localhost:8080, but are instead using localhost. This is because Tomcat is listening to port 8080, while Apache is servicing requests using the default port of 80, which is being served by Apache.
Up Next: Next time, I'll take another look at server.xml while we configure Tomcat to receive requests from Microsoft's Internet Information Server (IIS).
Read more Using Tomcat columns.
Return to ONJava.com.