launchd is the OS X component which manages long running processes - daemons or services.
Apple has an introduction to launchd.
There's a mismatch between how launchd expects a daemon to behave, and how the default startup scripts for Tomcat (the application server used by the stand-alone Confluence distribution) operate. Launchd expects the process it starts to run forever, but 'catalina.sh start' starts the JVM to run Tomcat and then exits. Tomcat provides 'catalina.sh stop' to cleanly shut down Tomcat by connceting to a socket which Tomcat listens on, but launchd stops daemons by sending them a signal, which simply kills the process immediately if no specific handling is included.
To match Tomcat to launchd we need to write a wrapper shell script, which we add to $CATALINA_HOME/bin:
This shell script starts Tomcat, and then waits for the process to complete, so launchd is happy that Tomcat is still running. It also installs a signal handler, which calls the shutdown() function to cleanly shut down Tomcat when launchd signals the script.
You can try this script manually - start it, watch Confluence start, and then type ctrl-C, and see Confluence shut down cleanly (note that it won't shut down cleanly if Tomcat hasn't started yet - it takes a few seconds for Tomcat to start listening on the shutdown socket).
We also need a launchd .plist, to tell launchd how to start Tomcat:
This file needs to be placed in /Library/LaunchDaemons, which is the location for system-wide services which are not part of base OS X.
There are a number of things to note about this plist:
- The path to your Confluence installation has to be explicitly specified in four places. I don't know if there's a better solution to this.
- JAVA_HOME is set to use the default JDK. On 10.4.4 this is 1.4.2, if you want to use 1.5 you would need to change JAVA_HOME to /System/Library/Frameworks/JavaVM.framework/Versions/1.5.
- You need to change the UserName to the user you want Tomcat to run as.
To start and stop Confluence manually you use the commands:
sudo launchctl load -w confluence.plist
sudo launchctl unload -w confluence.plist
I confess that I don't understand the semantics of
launchctl start/stop - stopping a daemon seems to kill the process, but then launchd immediately restarts it.