Installing Apache Tomcat 6 on Mac OS X Leopard

March 23, 2010

Contents

Introduction

Installing Apache Tomcat 6 on Mac OS X is primarily a matter of downloading the appropriate packages and then following the UNIX installation instructions included with the package. However, OS X does have some peculiarities that make installation somewhat different than on your average UNIX box. These instructions will work with OS X 10.6 Snow Leopard and Java 6, but I have not verified it myself. I have also seen individuals using these instructions to get up and running on OS X 10.4 Tiger, but again I don't have the time to verify that everything works myself.

The OS X developer tools must be installed to compile the MOD_JK connector, Native Library, or the JSVC daemon. A few modifications to some make scripts and source code will have to be made to successfully compile JSVC. The developer tools can be found on the OS X installation DVD or online. The XCode command line development tools must be installed along with the graphical tools.

This document tends to be geared more toward setting up Tomcat in a development environment than a production environment. I have designed it to get you up and running as quickly as possible. Some tuning will probably have to be done if you are planning on running Tomcat in a production environment. For security reasons, you will probably also want to use the _appserver id that has already been created to run Tomcat instead of your admin id.

In this document, the environment variable $CATALINA_HOME refers to the directory where you installed the Tomcat binaries and $JAVA_HOME refers to the directory of the JAVA runtime environment. At the time of this writing, Tomcat 6.0.26 is the latest Tomcat 6.0.x release and requires at least Java 2 Standard Edition 5 (J2SE 5).

This document assumes that you are installing on the client version of OS X 10.5.8 Leopard or OS X 10.6 Snow Leopard with the latest security upgrades and JAVA 5 or JAVA 6 Framework. It also assumes you are logged in as an administrator.

I have tried to make this document as concise and direct to the point as possible. It is helpful to have some knowledge of the basic UNIX commands and permissions, the GNU build system, and the infamous httpd configuration file (httpd.conf).

Name Soup

JAVA has many names that as far as Java on OS X is concerned, are effectively the same. OS X comes with a complete JAVA environment for both program execution and program development. This document uses these names interchangeably.

Install Apache Tomcat 6

Set the JAVA_HOME environment variable

On OS X, the JAVA_HOME environment variable must be set to /Library/Java/Home directory, which in turn is a symbolic link that points to the current version of Java SDK you are running.

You don't have to set JAVA_HOME if you are just running Tomcat 6 and not compiling anything. It is also not absolutely necessary to set CATALINA_HOME. It is automatically set in the startup scripts. CATALINA_HOME is set here, because it is referenced throughout this document.

Execute the following commands in Terminal:

# All versions of OS X from 10.3 on up default to using BASH. However, if you upgraded OS X from an earlier version and imported your home directory, you may still be running TCSH. To find out what default login shell you are running and change it, go to the System Preferences Accounts pane. If the pane is locked, unlock it. Control Click on your account name and a contextual menu will appear. Click on Advanced Options. You will then be presented with a dialog where you can change the default login shell to whatever you want. You can also use the dscl utility to read and change the default login shell. Execute the following to read the directory service properties of your id.

dscl . read /Users/YourID

# Edit the shell local startup script with your favorite text editor.
nano ~/.profile (BASH shell)
nano ~/.tcsh (TCSH shell)

# Regardless of the editor you are using, take note of the text encoding and line feed type. Generally, Tomcat XML configuration files should be saved with UTF-8 encoding.

# Add the following lines to the .profile file: (BASH)
export JAVA_HOME=/Library/Java/Home
export CATALINA_HOME=/Library/Tomcat/Home

# Add the following lines to the .tcshrc file: (TCSH)
setenv JAVA_HOME /Library/Java/Home
setenv CATALINA_HOME /Library/Tomcat/Home

# Note: DO NOT PUT A TERMINATING SLASH at the end of these lines - e.g. /Library/Java/Home/
# A terminating slash will screw up many of the Tomcat build and run scripts.

# Save the .profile or .tcsh file

# Quit terminal and restart it

# Execute an env command to make sure JAVA_HOME and CATALINA_HOME are set correctly.
env

Download and install the Tomcat binaries

Download Tomcat 6 Binary Distribution Core (tar.gz) and Deployer (tar.gz) from the Apache Tomcat 6 Downloads Page. Download the Core apache-tomcat-6.0.x.tar.gz.

Create the Tomcat folder in an appropriate directory - /Library or /usr/local is recommended, but for development convenience Tomcat can be also installed in your home directory. Keep in mind that these instructions are designed for the installation of Tomcat in /Library. If another directory is used, you will have to assign appropriate permissions to that directory for these installation instructions to work.

Also, be aware that when you download files with the Safari browser, it may try to unpack the archive, leaving you with a file that does not need to be decompressed. So you only need to do a tar -xvf instead of tar -xvzf to unpack the archive.

Execute the following commands in Terminal:

# Change directories to Library
cd /Library

# Create the Tomcat directory and set an appropriate owner and group
mkdir Tomcat
chown username Tomcat
chgrp admin Tomcat

# Change directories to the newly created Tomcat directory and unpack the tar.gz files
cd Tomcat
tar -xvzf ~/Downloads/apache-tomcat-6.0.x.tar.gz
# or
tar -xvf ~/Downloads/apache-tomcat-6.0.x.tar

# Create a symbolic link that will always point to the current version Tomcat directory
ln -sfhv apache-tomcat-6.0.x Home

Edit tomcat-users.xml configuration file

You will need to add a name and password to the tomcat-users.xml configuration file to access the Tomcat management and administration programs.

Execute the following commands in Terminal:

# Change directories to the Tomcat configuration directory
cd Home/conf

# Edit the tomcat-users.xml file
nano tomcat-users.xml

# Add the following, where admin is the administrator
# name you assign and password is the password.
<user username="admin" password="password" roles="standard,manager,admin"/>

# The tomcat-users.xml file should look something like this:
<tomcat-users>
<!--
<roll rollname="tomcat"/>
<roll rollname="role1"/>
<user username="tomcat" password="tomcat" roles="tomcat" />
<user username="role1" password="tomcat" roles="role1" />
<user username="both" password="tomcat" roles="tomcat,role1" />
-->
<user username="admin" password="password" roles="standard,manager,admin"/>
</tomcat-users>

# Save the tomcat-users.xml file and quit the editor


Run and Test

Execute the following commands in Terminal:

# Change directories to where the Tomcat startup scripts are located
cd ../bin

# Remove the .bat scripts and .exe executables
rm *.bat *.exe

# Execute the Tomcat startup script
./startup.sh

# Check the Tomcat error log for errors
cd ../logs
less catalina.out

# Some have reported having trouble executing the startup scripts because the execute permission has not been set for some reason. You may have to do the following if this is the case:
cd ../bin
chmod 755 *.sh
# or if you want to tighten up the permissions on everything
chmod 750 *

From your web browser go to the URL http://localhost:8080/

You should see the Tomcat welcome screen.

Use the ./shutdown.sh script to stop Tomcat.

Secure Tomcat

Tomcat uses a mechanism called valves to filter IP source addresses. A particular type of valve element called a remote address filter, can be inserted into the Tomcat processing stream to allow or deny access to the server. The remote address filter may be used in several different containers: Engine, Host, or Context.

If you wish to secure your server for localhost use only, add the following lines to the engine container. Edit the $CATALINA_HOME/conf/server.xml configuration file. Find the lines ....

<!-- Define the top level container in our container hierarchy -->
<Engine name="Catalina" defaultHost="localhost" debug="0">

Add the following statements underneath ..

<!-- Allow only localhost to access this server -->
<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127.0.0.1,0:0:0:0:0:0:0:1%0,::1" />

For a complete description on the use of this mechanism see the Server Configuration Reference.

Setup Tomcat Java Server as a UNIX Daemon - JSVC

These instructions use jsvc to daemonize Tomcat, which is the more traditional UNIX like method of starting Tomcat.

Unpack and patch the java server daemon JSVC

The Java Server Daemon JSVC source code is included with the Tomcat 6.0.x binary release. You will need to patch two files - native/jsvc.h and support/apsupport.m4.

# Change directories to the Tomcat home directory
cd $CATALINA_HOME/bin

# Unpack the jsvc archive
tar -xvzf jsvc.tar.gz

# Change directories to the unpacked source directory
cd jsvc-src/native

# Edit jsvc.h and delete the following type definition for booleans
/* Definitions for booleans */
typedef enum {
false,
true
} bool;

# Replace the original boolean typedef with the following include
#include <stdbool.h>

# Save and close jsvc.h

# To compile jsvc on OS X 10.6 Snow Leopard you must make the following modifications to java.c. I haven't verified this patch myself, but it reportedly works.

# Edit java.c and replace the following:
# Line 141, replace libjvm_compat.dylib with libjvm.dylib
# Line 159, replace JNI_CreateJavaVM with JNI_CreateJavaVM_Impl

# Change directories to support
cd ../support

# Edit apsupport.m4

# Edit the following line ..
CFLAGS="$CFLAGS -DOS_DARWIN -DDSO_DYLD"

# and change it to
CFLAGS="$CFLAGS -DOS_DARWIN -DDSO_DLFCN"

# Save and close apsupport.m4

Compile JSVC

Execute the following commands to build the jsvc daemon and copy the daemon executable and startup script to the Tomcat bin directory. I'm not sure if jsvc will properly compile 64-bit on Snow Leopard. There is a patch at http://osdir.com/ml/issues-commons-apache/2010-02/msg00074.html, but I have not tried it myself.

The OS X developer tools must be installed.

# Move back up the directory tree
cd ..

# Create the configure file
sh support/buildconf.sh

# Create the make file
sh ./configure

# Build jsvc
make

# Move jsvc into bin
mv jsvc ..

# Copy the jsvc startup script into bin
cp native/Tomcat5.sh ..

# Change directories into bin
cd ..

# Add execute permissions to Tomcat5.sh
chmod 750 Tomcat5.sh

Edit the daemon startup script Tomcat5.sh

# Edit Tomcat5.sh
nano Tomcat5.sh

# Make sure the following environment variables are set correctly in
# the Tomcat5.sh startup script for your installation. It is recommended that you run
# Tomcat as a user other than root as to restrict Tomcat's access to the host machine.

JAVA_HOME=/Library/Java/Home
CATALINA_HOME=/Library/Tomcat/Home
DAEMON_HOME=$CATALINA_HOME/bin
TOMCAT_USER=<username>
# for multi instances adapt those lines.
TMP_DIR=/var/tmp
PID_FILE=/var/run/jsvc.pid
CATALINA_BASE=$CATALINA_HOME
CATALINA_OPTS=
CLASSPATH=\
$JAVA_HOME/lib/tools.jar:\
$CATALINA_HOME/bin/commons-daemon.jar:\
$CATALINA_HOME/bin/bootstrap.jar
case "$1" in
start)
#
# Start Tomcat
#
$DAEMON_HOME/jsvc \
.
.
.
stop)
#
# Stop Tomcat
#
$DAEMON_HOME/jsvc \

Start Tomcat as a Daemon

# Execute the startup script to start Tomcat as a daemon
# You must execute the daemon as root as it writes the
# daemon's process id to /var/run.
# If Tomcat is already running, first stop it.
sudo ./Tomcat5.sh start

# Check and see if it is running
ps -ax

# To stop the server ...
sudo ./Tomcat5.sh stop

Starting Tomcat at Boot Time

If you would like Tomcat to start at boot time, create a Launchd property list to load JSVC. Download tomcat-plist.tar.gz and execute the following commands in terminal.

# Change directories to the LaunchDaemons directory
cd /Library/LaunchDaemons

# Unpack the property list
sudo tar -xvzf ~/Downloads/tomcat-plist.tar.gz

# Make sure the property list is owned by root
sudo chown root org.apache.commons.jsvc.plist

# Test
sudo launchctl load /Library/LaunchDaemons/org.apache.commons.jsvc.plist

Install Apache HTTPD Tomcat Connector - MOD_JK

If you need to run Tomcat as well as the Apache HTTPD server, you can use the connector to pass requests from HTTPD to Tomcat.

An alternative to using the mod_jk connector is to use httpd's mod_proxy. The Tomcat Wiki includes a discussion on the alternatives to mod_jk.

Download and unpack the Apache HTTPD Tomcat Connector - JK 1.2

Download JK 1.2.x tomcat-connectors-1.2.x-src.tar.gz source release archive from the Apache Tomcat Connectors Page

Unpack the source code into the directory of your choice. /usr/local/src is a suggestion.

Keep in mind that this configuration is designed for only the most basic configuration of httpd. This documentation doesn't go into much detail about supporting virtual hosts.

You can ignore this paragraph if running on Snow Leopard. The Apache web server (HTTPD) shipped with OS X 10.5 Leopard is a universal binary compiled with support for all four processor architectures (PPC, PPC64, i386, x86_64). If you are compiling or cross-compiling for HTTPD running on a 64 bit processor (PowerPC G5, Core 2 Duo, Xeon) you can either compile the mod_jk module with 64-bit support or run httpd 32-bit by using the lipo command to strip out the 64-bit support from httpd (sudo lipo -thin ppc7400 -output /usr/sbin/httpd.ppc /usr/sbin/httpd) or (sudo lipo -thin i386 -output /usr/sbin/httpd.i386 /usr/sbin/httpd).

Build and install the connector

The OS X developer tools must be installed.

# Change to the JK source directory
cd /usr/local/src/tomcat-connectors-1.2.x-src/native

# Configure a make file to create a 32-bit binary (Leopard) or 64-bit binary (Snow Leopard) for the same architecture you are compiling on
./configure --with-apxs=/usr/sbin/apxs

# Configure a make file to create a 32/64-bit 4-way universal binary
CFLAGS='-arch ppc -arch i386 -arch ppc64 -arch x86_64' APXSLDFLAGS='-arch ppc -arch i386 -arch ppc64 -arch x86_64' ./configure --with-apxs=/usr/sbin/apxs

# With the most recent source release you have to clean for some reason
make clean

# Build the connector
make

# Install the connector
sudo make install

Configure the connector

I could never get the MOD_JK auto-configure feature to work, so I suggest configuring MOD_JK manually by using the MOD_JK quick start instructions.

The following configuration will redirect all http requests for the /example directory to be redirected to the example Tomcat application context.

Add the following configuration text to the end of httpd.conf,
or create a separate /etc/apache2/other/mod_jk.conf file and insert the following text:

# Load mod_jk module
# Update this path to match your modules location
LoadModule jk_module libexec/apache2/mod_jk.so
# Where to find workers.properties
# Update this path to match your conf directory location
# Put workers.properties in /etc/apache2 OR /etc/apache2/other
JkWorkersFile /etc/apache2/workers.properties
# Where to put jk shared memory
# Update this path to match your local state directory or logs directory
JkShmFile /var/log/apache2/mod_jk.shm
# Where to put jk logs
# Update this path to match your logs directory location (put mod_jk.log next to access_log)
JkLogFile /var/log/apache2/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] "
# Send everything for context /examples to worker named ajp13 (ajp13)
# If you are using virtual hosts you will need to put the following JkMounts in
# your apache2/extra/httpd-vhosts.conf file, maybe in the default
# ServerName localhost VirtualHost section or whatever is appropriate for your installation.
JkMount /examples/* ajp13
JkMount /host-manager/* ajp13
JkMount /docs/* ajp13
JkMount /manager/* ajp13

Create the file workers.properties in the same /etc/apache2/ or /etc/apache2/other/ directory by cutting and pasting the following configuration text:

#
# The workers that jk should create and work with
#
worker.list=ajp13

#
# Defining a worker named ajp13 and of type ajp13
# Note that the name and the type do not have to match.
#
worker.ajp13.type=ajp13
worker.ajp13.host=localhost
worker.ajp13.port=8009

Use the System Preferences Sharing panel or the apachectl utility to stop and restart the HTTPD server.

Execute the following commands in Terminal:

# Stop the HTTPD server if it's already running
sudo apachectl graceful-stop

# Start the HTTPD server
sudo apachectl start

From your web browser go to the URL http://localhost/examples/

You should see the Tomcat JSP Examples screen.

If things are not working as expected, first use the console utility or command line to check the httpd error log at /var/log/apache2/error_log. You should see something like [notice] Apache/2.2.11 (Unix) mod_ssl/2.2.11 OpenSSL/0.9.7l DAV/2 PHP/5.2.10 SVN/1.4.4 mod_jk/1.2.28 configured

Compile and Install Tomcat Native Library

If you are planning on running Tomcat in a production environment, it is advisable that you install the native library. The native library will improve the performance of your Tomcat installation.

The OS X developer tools must be installed.

Download and unpack Apache Portable Runtime (APR)

Download apr-1.3.x-src.tar.gz source release archive from the Apache APR Download Page

Unpack the source code into the directory of your choice. /usr/local/src is a suggestion.

Build and install APR

# Change to the APR source directory
cd /usr/local/src/apr-1.3.x

# Build the make file
./configure

# Users of 64-bit Java 6 should use the following configure command:
CFLAGS='-arch x86_64' ./configure

# Make the library
make

# Test the build (Takes a while)
make test

# Install APR
make install

Build the Tomcat Native Library

# Change directories to Tomcat Binaries
cd /Library/Tomcat/Home/bin

# Unpack the native library source code
tar -xvzf tomcat-native.tar.gz

# Change into the native source directory
cd tomcat-native-1.1.20-src/jni/native

# Build the make file for Java 5
./configure --with-apr=/usr/local/apr --with-ssl=/usr # With SSL
./configure --with-apr=/usr/local/apr --without-ssl # Without SSL

# Some have reported having to use the --with-java-home option even with Java 5
./configure --with-apr=/usr/local/apr --with-ssl=/usr --with-java-home=/System/Library/Frameworks/JavaVM.framework/Versions/1.5 # With SSL
./configure --with-apr=/usr/local/apr --without-ssl --with-java-home=/System/Library/Frameworks/JavaVM.framework/Versions/1.5 # Without SSL

# Users of 64-bit Java 6 should use the following configure command:
CFLAGS='-arch x86_64' ./configure --with-apr=/usr/local/apr --with-ssl=/usr/ssl --with-java-home=/System/Library/Frameworks/JavaVM.framework/Versions/1.6

# Make
make

# Copy the native library to /usr/lib/java
sudo cp .libs/libtcnative-1.0.1.20.dylib /usr/lib/java

# Create a symbolic link in /usr/lib/java to the native library
cd /usr/lib/java
sudo ln -sfhv libtcnative-1.0.1.20.dylib libtcnative-1.dylib
sudo ln -sfhv libtcnative-1.dylib libtcnative-1.jnilib

# Restart Tomcat
cd /Library/Tomcat/Home/bin
./shutdown.sh
./startup.sh

# Check the log to make sure APR is loaded
cd ../logs
tail -n 30 catalina.out
You should see the following message:
INFO: Loaded APR based Apache Tomcat Native library 1.1.20.

# There has been a problem with the pollersize setting that has appeared, disappeared and then reappeared. If you get the error:
INFO: Failed to create poller with specified size of 8192
You will have to edit server.xml.

cd ../conf
nano server.xml

# Change the following line ...
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

# To ..
<Connector port="8009" protocol="AJP/1.3" pollerSize="1024" redirectPort="8443" />

Configure Tomcat for Database Access

The database installation instructions and sample JSP program included with the Tomcat distribution docs will work on OS X 10.5 and J2SE 1.5, but you will have to use an updated database configuration file as shown below. I used the following combination of packages:

Be sure to look at the Application Developer's Guide documentation for an example on how to build your first application. It includes a sample build.xml file and source directory structure that you can use as a template for your other projects.

MySQL Database

There are a number of sites around the internet that cover the installation of MySQL on OS X Leopard. Here are a few:

Compiling and Installing MySQL on OS X Leopard

Compiling MySQL on OS X

Installing MySQL on OS X

MySQL Database Server

Apache Xalan-J 2.7.1

The Java 5 SDK on OS X ships with an old version of Xalan, it's a good idea to update to the latest version. The Apache Xalan XML transformation processor can be downloaded from the Apache Xalan site. I recommend downloading the source code archive xalan-j_2_7_1-src-2jars.tar.gz and compiling it.
You will need to convert the CRLF line endings in build.sh to LF line endings.
Execute the command: perl -pi -e 's,\r\n,\n,' build.sh
To compile the complete package execute a sh build.sh all command in terminal. To compile the documentation execute a sh build.sh docs command.

Copy the files serializer.jar and xalan.jar from the build folder to /Library/Java/Extensions folder.

Apache Xerces-J 2.9.0

Upadating the XML parser is also a good idea as you should keep Xerces and Xalan in sync. The Xerces XML parser can be downloaded from the Apache Xerces site. I recommend downloading the source code archive Xerces-J-src.2.9.0.tar.gz and compiling it. To build Xerces you will also need the tools archive Xerces-J-tools.2.9.0.tar.gz. The tools folder must be put under the main Xerces source folder. To compile the complete package with documentation execute a sh build.sh all command in terminal.

Copy the files resolver.jar, xercesImpl.jar, and xml-apis.jar.jar from the build folder to /Library/Java/Extensions folder.

MySQL Connector/J

The MySQL Connector can be downloaded from the MySQL AB Connector/J 5.1 site. See Connecter/J versions.

The Connector/J mysql-connector-java-5.1.5-bin.jar file should be copied to $CATALINA_HOME/lib or /Library/Java/Extensions folder.

Jakarta Standard Taglibs 1.1.2

The Standard Taglibs files jstl.jar and standard.jar are included with the Tomcat sample code at $CATALINA_HOME/webapps/examples/WEB-INF/lib, but it is useful to know where they came from. You can download the standard tag library from the Jakarta Taglibs project.

Sample Database JSP Example Program Configuration File

The database configuration XML should not be placed in server.xml, but should be placed in it's own separate context.xml configuration file located in the DBTest/web/META-INF directory.

Create the file context.xml in the META-INF directory and include the following:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/DBTest" docBase="DBTest"
debug="5" reloadable="true" crossContext="true" >

<Logger className="org.apache.catalina.logger.FileLogger"
prefix="localhost_DBTest_log." suffix=".txt"
timestamp="true" />

<Resource name="jdbc/TestDB"
auth="Container"
type="javax.sql.DataSource" maxActive="100"
maxIdle="30"
maxWait="10000"
username="javauser"
password="javadude"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/javatest?autoReconnect=true" />

</Context>

Troubleshooting

These instructions install Tomcat in /Library/Tomcat. If you received the error "Cannot find /Library/Tomcat/Home/bin/setclasspath.sh," you are probably trying to install Tomcat in your home directory Library (~/Library). Either install Tomcat in the root Library (/Library) or point CATALINA_HOME to your home directory Tomcat installation directory, probably something like CATALINA_HOME=/Users/username/Library/Tomcat/Home. A basic installation doesn't require setting CATALINA_HOME or JAVA_HOME for that matter.

User Comments

I had one app that wouldn't start up because the heap size was too small. In trying to debug that I enhanced JAVA__OPTS in Tomcat5.sh, and added it to the jsvc line. Here are the last changes: JAVA_OPTS="$JAVA_OPTS -Dcatalina.base=/tmp/catalina -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties -Xms512m -Xmx512m"

Only small comment i would like to make is that in the "Edit the daemon startup script Tomcat5.sh" under the CLASSPATH section of the script, I don't have tools.jar on my mac and so initially the script wasn't working. Reading around I saw that classes.jar can be used instead and this worked from me:
CLASSPATH=\$JAVA_HOME/Classes/classes.jar:\

Under snow 10.6.3 the file .profile can be named .bash_profile and into tomcat-users.xml must be create a <role rolename="username"> and <user username="tomcat" password="tomcat" roles="tomcat,username">

Links

Feedback

Please let me know if you found this page useful or have any other comments. Thank you to all who have mailed in your suggestions. Your feedback has helped make this document more accurate and complete.

Comments:

Your Email (Optional):
Include an email address if you would like a reply.