Apache Tomcat Integration HowTo

Overview

This is to explain and understand how to integrate Apache and Tomcat to support Java Server Pages (JSP) and Servlets using Apache on your website. Although this setup worked for this particular environment, I can make no guarantees that it will work for yours, but it should with some tweaking. I have spent a lot of time gathering several resources in order to get this to work. Many portions of these resources have been deprecated and required a few workarounds. It is my intention that this tutorial will help anyone that has attempted to install such a system without success. If you find any inconsistencies within this tutorial, please notify me using the contact form.

System Details

The system used in this tutorial has the following installed:

Operating System: RHEL 4 AS (http://www.redhat.com/)

WebServer: Apache 2.x (http://www.apache.org/)

JDK: JDK 5.x (http://java.sun.com/j2se/1.5.0/download.jsp)

Servlet Container: Tomcat 5.x (http://tomcat.apache.org/)

Tomcat Connecter: Jakarta Tomcat Connector mod_jk.so (not mod_jk2.so)

RHEL 4 AS

If you are planning to use RHEL there many howto’s available on the I will google be your best friend for this. If you are planning to use other distro for those also there are many howto’s available which you can refer to.

Apache 2

Since installing Apache is beyond the scope of this tutorial, I will assume that you already have Apache 2.0.x installed and running. If you need instructions on installing and configuring Apache 2.0.x please refer to the documentation at the Apache website.

Installing JDK (Java Development Kit)

In order to run Tomcat, you will need to install JDK and set the JAVA_HOME environment variable to identify the location of the JDK environment on your system. I have chosen to use JDK 5.0.

  • You can download JDK 5.0 at http://java.sun.com/j2se/1.5.0/download.jsp.
  • Click on Download JDK 5.0 Update 6 to go to the download page.
  • Click Accept to accept the license agreement.
  • Next choose the Linux self-extracting file. This is the download for the self-extracting binary file rather than the rpm.
  • Download to your preferred download directory. Change to that directory and make it executable by executing the following command:
	chmod +x jdk-1_5_0_06-linux-i586.bin
  • Now execute the file:
    	./jdk-1_5_0_06-linux-i586.bin
  • You should now have a new directory called j2sdk1.5-sun. Now move this directory to the location where it should be run. I choose /usr/.
    	mv j2sdk1.5-sun /usr/
  • Now create a symbolic link called java to JAVA_HOME by the following command. This allows you to easily switch back and forth between different jvms should you ever need to
    	cd /usr
    	ln -s j2sdk1.5-sun java
  • Now we need to set the JAVA_HOME environment variable. Create java.sh file in /etc/profile.d with following content.
    	JAVA_HOME=/usr/java
    	export JAVA_HOME

/etc/profile is executed at startup and when a user logs into the system. In order to update the environment you need to run “. /etc/profile” on command prompt.

  • Check to make sure JAVA_HOME is defined correctly by executing the command below. This should report the location of the Java SDK which should be /usr/java
    	echo $JAVA_HOME
  • Now test Java with the following command. You should be returned with /usr/bin/java. If so, you have successfully completed this section.
    	which java

Installing Tomcat

In this section you will download and install Apache Tomcat 5.5.25. For this particular setup, there is no need to build the package from source, we will download the binary version.

  • Download the binary version to your preferred download directory from here: http://tomcat.apache.org/download-55.cgi. Choose the tar.gz from the core section for 5.5.25.
  • Now extract the files using the following command:
     tar -xvzf apache-tomcat-5.5.25.tar.gz
  • You should now have a new directory called apache-tomcat-5.5.25. Now move this directory to the location where it should be installed. Again, I choose /usr/local/. Note that this location will be referred to as CATALINA_HOME in the Tomcat documentation.
     mv apache-tomcat-5.5.25 /usr/local
  • Next change to the /usr/local directory.
     cd /usr/local
  • Now create a symbolic link called apache-tomcat to CATALINA_HOME by the following command.
     ln -s apache-tomcat-5.5.15 apache-tomcat
  • You should now be able to start and stop Tomcat from the CATALINA_HOME/bin directory. If you are using another shell other than the bash shell you will nee to add sh to the beginning of the command. You should now be able to test that Tomcat is installed by starting it and opening your browser and entering http://localhost:8080 into your browser. Port 8080 is the default port for Tomcat. If you plan to access this page remotely, be sure to forward the respective port to your server’s IP address within your router. You should now see the Tomcat welcome page that contains links to Tomcat documentation as well as sample JSP/Servlet scripts. Verify that Tomcat is running by executing some of the examples found on the welcome page.
     cd /usr/local/apache-tomcat
     sh catalina.sh start
  • To shutdown the server, you will need to execute the following command. Feel free to try it, but for now we will leave Tomcat running.
      sh catalina.sh stop

Installing the Connector

At this point, Apache and Tomcat should be working separately in standalone mode. You can run Tomcat in standalone mode as an alternative to Apache. In fact, in some cases, it is said that Tomcat standalone is faster than serving static content from Apache and dynamic content from Tomcat. However, there are the following compelling reasons to use Apache as the front end:

  1. You can use Apache to buffer slow connections. Tomcat uses java.io, which uses a thread for each request, so Tomcat can run out of connections as the number of slow requests grows. This could be an issue if your application supports a large number of dial-up users.
  2. You can use a connector such as mod_jk to load balance amongst several Tomcat instances.
  3. You can take advantage of Apache features such as cgi and PHP.
  4. You can take advantage of Apache modules such as mod_rewrite, mod_headers, and mod_expire.
  5. You can isolate virtual hosts in their own Tomcat instances.

The increased functionality obtained by using Apache on the front end can outweigh the effort required to install and configure a connector.

Selecting a Connector

Development on the mod_jk2 connector was discontinued on 11/15/2004; therefore, you no longer have to decide between the mod_jk and mod_jk2 connectors. Use the mod_jk connector. It has been around a long while and is very stable.

Building the mod_jk Connector

The mod_jk connector is the communication link between Apache and Tomcat. It listens on a defined port for requests from Apache and forwards those requests to Tomcat.

Install the following Red Hat RPMs if they are not already installed:

  • libtool
  • automake
  • autoconf

Download the jk connector source from http://www.apache.org/dist/jakarta/tomcat-connectors/jk/. I used jakarta-tomcat-connectors-1.2.8-src.tar.gz.

Unzip the contents of the file into your download directory as follows:

     tar xvzf jakarta-tomcat-connectors-1.2.8-src.tar.gz

This will create a folder called jakarta-tomcat-connectors-1.2.8-src. Move this folder to wherever you store source files on your system. I chose /usr/src. Here is the command I issued from inside the download directory:

     mv jakarta-tomcat-connectors-1.2.8-src /usr/src

I refer to the folder where the connector source is installed as CONN_SRC_HOME. In my case CONN_SRC_HOME = /usr/src/jakarta-tomcat-connectors-1.2.8-src.

Change to directory CONN_SRC_HOME/jk/native and run the buildconf.sh script as follows:

     ./buildconf.sh

This will create the CONN_SRC_HOME/jk/native/configure file. Run the configure script with the path to the apxs file on your system. If you installed Apache using the Red Hat RPM, apxs should be located at /usr/sbin/apxs.

     ./configure --with-apxs=/usr/sbin/apxs

Build mod_jk with the following command:

     make

If you see missing object errors, try this alternate command:

     make LIBTOOL=/etc/httpd/build/libtool

If all went well, the mod_jk.so file was successfully created. Manually copy it to Apache’s shared object files directory:

     cp CONN_SRC_HOME/jk/native/apache-2.0/mod_jk.so /etc/httpd/modules

Configuring Tomcat

workers.properties

The workers.properties file contains information so mod_jk can connect to the Tomcat worker processes.

Place the following workers.properties file in the /etc/httpd/conf directory:

     # workers.properties - ajp13
     #
     # List workers
     worker.list=wrkr
     #
     # Define wrkr
     worker.wrkr.port=8009
     worker.wrkr.host=localhost
     worker.wrkr.type=ajp13
     worker.wrkr.connection_pool_size=10
     worker.wrkr.connection_pool_timeout=600
     worker.wrkr.socket_timeout=300

Note:

  1. There is an example workers.properties file located in the CONN_SRC_HOME/jk/conf directory. The example file provides a lot of useful information and insight into the workers.properties file, but it contains so much information that it can be confusing. I recommend using it as a learning tool but creating your own workers.properties file from scratch.
  2. The configuration above assumes Apache and Tomcat are located on the same box and requests are forwarded to Tomcat using type ajp13 workers. Type ajp13 workers forward requests to out-of-process Tomcat workers using the ajpv13 protocol over TCP/IP sockets.
  3. The name of the worker in the JkMount directive in httpd.conf must match the name of the worker in worker.list (“wrkr” in the configuration above).

server.xml

The CATALINA_HOME/conf/server.xml file contains Tomcat server configuration information. The default server.xml is great for verifying that Tomcat works in standalone mode and for viewing the examples that come with the application, but it contains so much information that it can be confusing. I recommend saving it for future reference and creating a new server.xml.

Save the default server.xml as follows:

     mv CATALINA_HOME/conf/server.xml CATALINA_HOME/conf/server.xml.orig

Copy the following into a new server.xml file:

    	<Server port="8005" shutdown="0fbb9aebcbfbef203eca71b6be367859" debug="0">
    		<Service name="Tomcat-Apache">

    			<Connector address="127.0.0.1"
    				port="8009"
    				minProcessors="5"
    				maxProcessors="75"
    				enableLookups="false"
    				protocol="AJP/1.3"
    				debug="0"/>

    			<Engine name="appserver"
    				debug="0"
    				defaultHost="{YOUR_DOMAIN}">

    			<Host name="{YOUR_DOMAIN}"
    				appBase="/usr/local/tomcat/webapps"
    				autoDeploy="false"
    				deployOnStartup="false"
    				unpackWARs="false"
    				deployXML="true"
    				debug="0"/>

    			</Engine>

    		</Service>

    	</Server>

If you do keep the default server.xml, make sure you comment out any other connectors besides mod_jk that are listening on port 8009. The default file comes with the Coyote/JK2 connector enabled for the Tomcat-Standalone service. This will conflict with the mod_jk connector in your Tomcat-Apache service. You should comment this connector out. It isn’t needed when you connect directly to Tomcat in standalone mode (port 8080), so I’m not sure why this connector is enabled by default.

The Connector address defines the interface that Tomcat will listen on for mod_jk requests from Apache. In my configuration, Apache and Tomcat reside on the same box, so I have set the address to the loopback address. The default is for Tomcat to listen on all interfaces, so restricting it to the loopback interface improves security.

The Server shutdown property is the text string that is sent over a socket connection to stop Tomcat. The default value is “SHUTDOWN”. The shutdown port is always on the loopback interface, which provides host-level protection. However, there is the possibility that the host could be compromised and someone could send the command SHUTDOWN to all ports and knock Tomcat offline. To prevent this, replace the default value with one that is difficult to guess. Do not use the example string above. Create your own by feeding random bytes into md5sum as follows:

     head -1024c /dev/random | md5sum

Change the permissions on server.xml to prevent unprivileged users from reading the shutdown string:

     chmod 600 CATALINA_HOME/conf/server.xml

Configuring Apache

Apache is configured with directives placed in the main Apache configuration file, /etc/httpd/conf/httpd.conf. In addition, Apache 2 has configuration files for perl, php, and ssl located in /etc/httpd/conf.d/.

Rename the /etc/httpd/conf.d/ssl.conf file to ssl.conf.bak. The default Red Hat Apache 2 installation comes with ssl support enabled. If ssl is needed, you can re-enable it after you have successfully integrated Apache and Tomcat.

httpd.conf

You will notice that there are three sections labeled in the httpd.conf file supplied by Red Hat: (1) Global Environment, (2) Main Server Configuration, and (3) Virtual Hosts.

Add the following to the bottom of the existing LoadModule directives in the Global Environment section:

     LoadModule jk_module modules/mod_jk.so

Add the following to the bottom of the Main Server Configuration section:

     JkWorkersFile "/etc/httpd/conf/workers.properties"
     JkLogFile "/etc/httpd/logs/mod_jk.log"
     JkLogLevel info
     JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"

Set up a Virtual Host directive in the Virtual Hosts section of httpd.conf. Below is an example of how to set up the {YOUR_DOMAIN} website so Tomcat handles all jsp pages and requests with “servlet” in the path:

    	NameVirtualHost 127.0.0.1:80

    	<VirtualHost 127.0.0.1:80>
    		ServerAdmin webmaster@{YOUR_DOMAIN}
    		ServerName {YOUR_DOMAIN}
    		DocumentRoot /home/tomcat/webapps/{YOUR_DOMAIN}/{YOUR_APPLICATION}
    		ErrorLog /home/tomcat/webapps/{YOUR_DOMAIN}/logs/error_log
    		CustomLog /home/tomcat/webapps/{YOUR_DOMAIN}/logs/access_log common
    		JkMount /*.jsp wrkr
    		JkMount /servlet/* wrkr
    		# Deny direct access to WEB-INF
    		<LocationMatch ".*WEB-INF.*">
    			AllowOverride None
    			deny from all
    		</LocationMatch>
    	</VirtualHost>

The argument for the NameVirtualHost directive must match exactly the argument for the VirtualHost directive (127.0.0.1:80).

The JkMount directive specifies url patterns of requests that will be forwarded to Tomcat for processing.

You can test your Apache configuration by typing the following:

	httpd -t -D DUMP_VHOSTS

You should get something like the following response:

    	127.0.0.1:80           is a NameVirtualHost
    		default server {YOUR_DOMAIN} (/etc/httpd/conf/httpd.conf:1056)
    		port 80 namevhost {YOUR_DOMAIN} (/etc/httpd/conf/httpd.conf:1056)
    	Syntax OK

Setting Up {YOUR_DOMAIN}

{YOUR_DOMAIN} does not need to be a domain name with a DNS entry. For testing purposes, you can set up any domain you want in the /etc/hosts file of the machine that you will be using to access your application.

The example below shows the entry for {YOUR_DOMAIN} when running Apache and Tomcat on a single machine, typical for a development computer.

     127.0.0.1	{YOUR_DOMAIN}

Testing Apache

We will create and install a simple Hello World html page so we can test to make sure Apache handles requests for static html pages. Hello World HTMLCopy the following text into a file called HelloWorld.html and install the file in the /usr/local/tomcat/webapps/{YOUR_DOMAIN}/{YOUR_APPLICATION} directory.

     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     <html>
     <head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     <title>Hello World HTML!</title>
     </head>
     <body>
     <h1>Hello World HTML!</h1>
     </body>
     </html>

If Apache has not been restarted since you added your virtual host, do so as follows:

     service httpd restart

You should now be able to type ttp://{YOUR_DOMAIN}/HelloWorld.html into your browser and see the always-exciting “Hello World” message.

Testing Tomcat

We will create and install a simple Hello World jsp page and servlet so we can test to make sure Apache forwards servlet requests to Tomcat for handling.

Hello World JSP

Copy the following text into a file called HelloWorld.jsp and install the file in the /home/tomcat/webapps/{YOUR_DOMAIN} directory.

    	<%@ page contentType="text/html;charset=WINDOWS-1252"%>
    	<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    	<html>
    	<head>
    	<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    	<title>Hello World JSP</title>
    	</head>
    	<body>
    	<h1><% out.println(" Hello World JSP!"); %></h1>
    	</body>
    	</html>

Hello World Servlet

Copy the following into a file called HelloWorld.java:

    	import java.io.*;
    	import javax.servlet.*;
    	import javax.servlet.http.*;
    	public class HelloWorld
    		extends HttpServlet {
    			public void doGet(HttpServletRequest request,
    				HttpServletResponse response)
    				throws IOException, ServletException {
    					response.setContentType("text/html");
    					PrintWriter out = response.getWriter();
    					out.println("Hello World Servlet!");
    				}
    		}

Compile the source into a class file as follows:

    	javac -classpath /usr/local/jakarta-tomcat/common/lib/servlet.jar HelloWorld.java

This will create a file called HelloWorld.class. Copy the HelloWorld.class file to the /usr/local/tomcat/webapps/{YOUR_DOMAIN}/{YOUR_APPLICATION}/WEB-INF/classes directory.

Tomcat Application

The web.xml file is where a servlet name is mapped to a URL pattern so Tomcat can run your servlet when requested. Below is the web.xml file that runs the HelloWorld servlet whenever the URL http://{YOUR_DOMAIN}/servlet/HelloWorld is entered in the browser:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

    <web-app>
    	<servlet>
    		<servlet-name>HelloWorld</servlet-name>
    		<servlet-class>HelloWorld</servlet-class>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>HelloWorld</servlet-name>
    		<url-pattern>/servlet/HelloWorld</url-pattern>
    	</servlet-mapping>

    </web-app>

Restart Tomcat as follows:

    	/CATALINA_HOME/bin/catalina.sh start
    	/CATALINA_HOME/bin/catalina.sh stop

Restart Apache as follows:

    	service httpd restart

You should now be able to type the following into your browser and see the always-exciting “Hello World” message:

http://{YOUR_DOMAIN}/HelloWorld.jsp

http://{YOUR_DOMAIN}/servlet/HelloWorld

Troubleshooting

Log Files To Watch

/home/tomcat/webapps/{YOUR_DOMAIN}/logs/error_log

Look here for clues to Apache httpd.conf configuration issues, for example VirtualHost setup.

CATALINA_HOME/logs/catalina.out

Look here for clues to Tomcat server.xml configuration issues. This file is written to when Tomcat starts and stops. It also catches System.out and System.err.

CATALINA_HOME/logs/tomcat.log

Look here for clues to all Tomcat issues. This is the main Tomcat log file.

/etc/httpd/logs/mod_jk.log

Look here for clues to mod_jk configuration issues.

Monitoring Connections

The following command can be used to monitor the Apache, Tomcat, and mod_jk connections:

    	netstat -vatn | grep 80

Below is output from running this command. Line numbers have been added to the beginning of each line for discussion purposes.

	1 tcp        0      0 127.0.0.1:8005          0.0.0.0:*               LISTEN
	2 tcp        0      0 127.0.0.1:8009          0.0.0.0:*               LISTEN
	3 tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
	4 tcp        0      0 127.0.0.1:8009          127.0.0.1:34449         ESTABLISHED
	5 tcp        0      0 127.0.0.1:34449         127.0.0.1:8009          ESTABLISHED

Note:

  1. Line 1 shows Tomcat listening on port 8005 for the shutdown command.
  2. Line 2 shows Tomcat listening on port 8009 for requests from Apache.
  3. Line 3 shows Apache listening on port 80 for user requests.
  4. Line 4 shows the Tomcat end of a mod_jk connection.
  5. Line 5 shows the Apache end of a mod_jk connection.

Be the first to comment

Leave a Reply

Your email address will not be published.


*


CommentLuv badge