March 9, 2021
Hot Topics:

Server-Side Development on Mac OS X: Launching Tomcat

  • By Ian McFarland
  • Send Email »
  • More Articles »

Automatically Starting Tomcat at Boot Time

Rather than having startup scripts in a location like /etc/rc.d as you would find on SysV Unix, for instance, startup scripts for OS X live in /System/Library/StartupItems, in a directory named for the service. Inside the directory are a few files, the most important being the actual startup script, which must be named the same as the directory containing it. This script is a simple shell script and makes use of some library routines contained in other scripts. We'll see that in the source code below. And of course, the instructions below apply equally to any other service you may want to launch on startup, e.g., a database server or your own Java server.

To start out, make a new directory: sudo mkdir /System/Library/StartupItems/Tomcat

Then, inside of that directory, create your startup script: sudo vi /System/Library/StartupItems/Tomcat/Tomcat

(You can use emacs if you like, or any other text editor. If you use a GUI text editor like TextEdit, BBEdit, or ProjectBuilder, though, you may need to write the file in a directory you have write access to and then copy it into place. There are ways to launch a GUI text editor as root, but they're beyond the scope of this article.)

This is what your Tomcat file should look like:


. /etc/rc.common
export JAVA_HOME=/usr

if [ "${TOMCAT}" = "-YES-" ]; then
    ConsoleMessage "Starting Tomcat Servlet/JSP Server"

Listing 1. /System/Library/StartupItems/Tomcat/Tomcat

We'll also need to make it executable: sudo chmod +x /System/Library/StartupItems/Tomcat/Tomcat

Pretty simple. As you can probably make out, this script runs /etc/rc.common (which has a bunch of utility code in it) and then checks to see if the variable TOMCAT is set to '-YES-'. If so, it runs our startup script. (You should change the path to startup.sh if you installed Tomcat somewhere else.)

We also need to add the following to the end of /etc/hostconfig:


This configuration file is brought in with rc.common, and lets us manage which services to start from a single file. (Most of these settings are actually manipulated by the System Preferences app.)

And one last required file, /System/Library/StartupItems/Tomcat/StartupParameters.plist,


Description = "Tomcat Servlet/JSP Server"; Provides = ("Tomcat"); Requires = ("Resolver"); OrderPreference = "None"; Messages = { start = "Starting Tomcat Servlet/JSP Server"; stop = "Stopping Tomcat Servlet/JSP Server"; }; }

Listing 2. /System/Library/StartupItems/Tomcat/StartupParameters.plist

This file tells the OS about any dependencies our module may have. In this case, it tells the OS that we want to start after the Resolver is up and running, and this is important so that we can get nameservice to resolve any hostnames we may be using for bind addresses or Name Virtual Hosts. It also tells the OS that we provide a service called Tomcat, so that other modules can say they depend on us. (You may, for example, write a service that needs Tomcat to be running before it can start. This is how you would regulate that startup requirement on OS X.)

One other set of files I should touch on reside in the Resources directory, the Localizable.strings files. These are optional localization files, living inside of directories named for the language they support, (e.g., German.lproj) that contain replacement strings to use in messages. They're not necessary to make your startup script work, so we'll leave them out of the discussion. (These are covered in my upcoming book, Java Development and Mac OS X.)

This configuration does pose one problem, though. Since all the startup scripts are run as root, this gives our Tomcat install root permissions, and that is a bad thing to do. You can get away with it if you're behind a firewall and you trust everyone else behind that firewall, but you should never run a publicly accessible Tomcat server that way, as it could pose a security risk.

Running as an Unprivileged User

Probably the best thing to do is to create a new unprivileged user to use to run Tomcat. Let's create a new Tomcat user. If you've done this before on a Unix machine, unless you used NIS, your instinct is probably to modify the /etc/passwd file. OS X uses NetInfo for system information, so we'll use the tools that come with the OS to set up the account.

Open the System Preferences panel, and click on the Users icon (grouped under System).

Click the New User... button, which will bring up the New User dialog. Enter Tomcat Role Account (or something similar) into the Name: box, and tomcat into the Short Name: box. Of course it doesn't matter much whether you choose a login picture. And you needn't bother with the Password tab, because we're about to star out the login so that nobody can log in as tomcat. (If you're worried about people getting into your machine in the five minutes between creating the account and starring out the password, just enter something obscure into the boxes on the password tab. You won't have to remember it later.) Click save, and OS X will create the account, along with a home directory which we will discard shortly.

Illustration: NetInfo

Figure 1. The System Preferences New User dialog.

Next, open NetInfo Manager (also in /Applications/Utilities) and browse down to Users in the middle pane. Be careful while you're using this app, as it contains key information your machine needs to start up, and to allow you to log in. If you make a mistake, or even if you think you may have made a mistake, it's best to revert to saved (Domain: Revert to Saved or Cmd-U) and try again. You may wish to save a backup (Domain: Save Backup...) before you start. That way, if you really muck things up, you can restore from the backup you just made.

Select 'tomcat', and click on the lock icon at the bottom of the window where it says, "Click the lock to make changes." As with sudo, you'll need to give your password and need to be an administrator on the machine.

Illustration: NetInfo

Figure 2. The NetInfo Manager window after editing user tomcat.

In the table at the bottom of the window, you'll modify a few values:

passwd*'Starring out' the password prevents users logging into this account. (No password matches '*'.)
shell/bin/shYou need to have a shell of some sort in which to run Java. /bin/tcsh is fine, too.
home/dev/nullNot having a home directory prevents the user from logging in.
gid-2-2 is group nobody, 1 is group daemon. You can choose which you prefer, based on local constraints. Both groups are typically reserved for unprivileged users.

You'll want to delete some entries, too: sharedDir, _writers_passwd, _writers_picture, _shadow_passwd, hint, and picture.

Do this by selecting the item and pressing Cmd-R or by using Delete from the Edit menu, not by pressing the delete button at the top of the window. That button is the Delete Selected Directory button, which is not what you want. If you get things wrong, revert and try again.

The above assumes you're using OS X Client. User creation is similar, but slightly different under OS X Server, and is accomplished using the Server Adminstrator application. More details on this, and on how NetInfo is managed in general, can be found in the Apple document Understanding and Using NetInfo.

Now that the user is set up, we can go back and modify our startup script to use it. The change is in bold.


. /etc/rc.common
export JAVA_HOME=/usr

if [ "${TOMCAT}" = "-YES-" ]; then
    ConsoleMessage "Starting Tomcat Servlet/JSP Server"
    su tomcat - /Library/Tomcat/bin/startup.sh

Listing 3. /System/Library/StartupItems/Tomcat/Tomcat, modified to run as user tomcat.

We'll also need to change the ownership of the files in /Library/Tomcat so that they're writable by user tomcat. And to make the installation easier to administer from the finder, you may also want to change the group ownership to the group you want to be able to administer the server. Group admin and group wheel are both good defaults, since both groups only contain users with administrative access. Group admin is specifically the administrators' group, and anyone in admin can use sudo to modify files anyway; but if you have a broader development team that needs access, you may want to set up a new group, perhaps one called tomcat.

sudo chown -R tomcat:admin /Library/Tomcat/*

It's also very handy to make /Library/Tomcat/webapps group writable, so that you can easily install .war files by dragging them into the webapps folder from the finder:

sudo chmod g+w /Library/Tomcat/webapps/

This will also be helpful during development, as you won't have to sudo in order to install newly built servlet code. Anyone in group admin will be able to drag .war files directly into the webapps directory.

You can still stop Tomcat by running:

sudo /Library/Tomcat/bin/shutdown.sh

...but from now on you should start Tomcat by running:

sudo /System/Library/StartupItems/Tomcat/Tomcat

This way it will run with the right permissions.

Next time, we'll see how to set up Apache and Tomcat to work together. This, also, is very easy to do. And in the last installment in this series, we'll see how to get set up with Project Builder, Apple's free industrial-strength IDE, to build Web apps.

About the Author

Ian McFarland is the president of Neo Ventures Ltd., a software consulting company in San Francisco. Previously, he served as senior director of technology for Hollywood Stock Exchange and Java Evangelist for Symantec Internet Tools.

This article was originally published on March 5, 2002

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date