PDA

View Full Version : Plist programming




Ikyo
Feb 28, 2008, 10:36 AM
I am not sure if this is the correct forum or not for this. I created a Plist on my mac mini to run Tomcat. It starts up perfectly and everything is great, but when I try to shut the machine down it will hang. If I posted the plist, could someone help me out with it? I am also wondering if anyone here is currently running Imap,POP3 and SMTP on their Mac without OSX Server.



Cromulent
Feb 28, 2008, 10:42 AM
I am not sure if this is the correct forum or not for this. I created a Plist on my mac mini to run Tomcat. It starts up perfectly and everything is great, but when I try to shut the machine down it will hang. If I posted the plist, could someone help me out with it? I am also wondering if anyone here is currently running Imap,POP3 and SMTP on their Mac without OSX Server.

You could try. You might get better help if you post in the Mac OS X Server forum though. As for the other problem go ahead, I'm sure quite a few people here have experience running e-mail servers either on Mac OS X or in Linux or another Unix type system, they are all pretty much the same.

Ikyo
Feb 28, 2008, 10:51 AM
Here is a copy of the PLIST. It is running from the LaunchDaemon folder:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

<key>Disabled</key>
<false/>

<key>EnvironmentVariables</key>
<dict>
<key>JAVA_HOME</key>
<string>/System/Library/Frameworks/JavaVM.framework/Home</string>
</dict>

<key>Label</key>
<string>org.apache.tomcat.tomcat6</string>

<key>ProgramArguments</key>
<array>
<string>/Library/Tomcat/Home/bin/catalina.sh</string>
<string>run</string>
</array>

<key>RunAtLoad</key>
<true/>

<key>ServiceDescription</key>
<string>Tomcat 6 Server</string>

</dict>
</plist>


In regards to the mail server, I have them installed, but keep getting user unknown when trying to connect. Is there a walk through on how to set it up? I have done it numerous times on a Linux machine, but it isn't working the same under OSX. It might also have to do with how I am calling the daemons. I am not sure.

robbieduncan
Feb 28, 2008, 10:57 AM
Does your startup script (the catalina.sh) provide the requried functions as defined in the documentation (http://developer.apple.com/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/StartupItems.html#//apple_ref/doc/uid/20002132)?

Ikyo
Feb 28, 2008, 11:17 AM
#!/bin/sh
# -----------------------------------------------------------------------------
# Start/Stop Script for the CATALINA Server
#
# Environment Variable Prequisites
#
# CATALINA_HOME May point at your Catalina "build" directory.
#
# CATALINA_BASE (Optional) Base directory for resolving dynamic portions
# of a Catalina installation. If not present, resolves to
# the same directory that CATALINA_HOME points to.
#
# CATALINA_OPTS (Optional) Java runtime options used when the "start",
# "stop", or "run" command is executed.
#
# CATALINA_TMPDIR (Optional) Directory path location of temporary directory
# the JVM should use (java.io.tmpdir). Defaults to
# $CATALINA_BASE/temp.
#
# JAVA_HOME Must point at your Java Development Kit installation.
# Required to run the with the "debug" or "javac" argument.
#
# JRE_HOME Must point at your Java Development Kit installation.
# Defaults to JAVA_HOME if empty.
#
# JAVA_OPTS (Optional) Java runtime options used when the "start",
# "stop", or "run" command is executed.
#
# JPDA_TRANSPORT (Optional) JPDA transport used when the "jpda start"
# command is executed. The default is "dt_socket".
#
# JPDA_ADDRESS (Optional) Java runtime options used when the "jpda start"
# command is executed. The default is 8000.
#
# JPDA_SUSPEND (Optional) Java runtime options used when the "jpda start"
# command is executed. Specifies whether JVM should suspend
# execution immediately after startup. Default is "n".
#
# JPDA_OPTS (Optional) Java runtime options used when the "jpda start"
# command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,
# and JPDA_SUSPEND are ignored. Thus, all required jpda
# options MUST be specified. The default is:
#
# -Xdebug -Xrunjdwp:transport=$JPDA_TRANSPORT,
# address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND
#
# JSSE_HOME (Optional) May point at your Java Secure Sockets Extension
# (JSSE) installation, whose JAR files will be added to the
# system class path used to start Tomcat.
#
# CATALINA_PID (Optional) Path of the file which should contains the pid
# of catalina startup java process, when start (fork) is used
#
# $Id: catalina.sh 522797 2007-03-27 07:10:29Z fhanik $
# -----------------------------------------------------------------------------

# OS specific support. $var _must_ be set to either true or false.
cygwin=false
os400=false
darwin=false
case "`uname`" in
CYGWIN*) cygwin=true;;
OS400*) os400=true;;
Darwin*) darwin=true;;
esac

# resolve links - $0 may be a softlink
PRG="$0"

while [ -h "$PRG" ]; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`/"$link"
fi
done

# Get standard environment variables
PRGDIR=`dirname "$PRG"`

# Only set CATALINA_HOME if not already set
[ -z "$CATALINA_HOME" ] && CATALINA_HOME=`cd "$PRGDIR/.." ; pwd`

if [ -r "$CATALINA_HOME"/bin/setenv.sh ]; then
. "$CATALINA_HOME"/bin/setenv.sh
fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$JRE_HOME" ] && JRE_HOME=`cygpath --unix "$JRE_HOME"`
[ -n "$CATALINA_HOME" ] && CATALINA_HOME=`cygpath --unix "$CATALINA_HOME"`
[ -n "$CATALINA_BASE" ] && CATALINA_BASE=`cygpath --unix "$CATALINA_BASE"`
[ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
[ -n "$JSSE_HOME" ] && JSSE_HOME=`cygpath --absolute --unix "$JSSE_HOME"`
fi

# For OS400
if $os400; then
# Set job priority to standard for interactive (interactive - 6) by using
# the interactive priority - 6, the helper threads that respond to requests
# will be running at the same priority as interactive jobs.
COMMAND='chgjob job('$JOBNAME') runpty(6)'
system $COMMAND

# Enable multi threading
export QIBM_MULTI_THREADED=Y
fi

# Get standard Java environment variables
if $os400; then
# -r will Only work on the os400 if the files are:
# 1. owned by the user
# 2. owned by the PRIMARY group of the user
# this will not work if the user belongs in secondary groups
BASEDIR="$CATALINA_HOME"
. "$CATALINA_HOME"/bin/setclasspath.sh
else
if [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]; then
BASEDIR="$CATALINA_HOME"
. "$CATALINA_HOME"/bin/setclasspath.sh
else
echo "Cannot find $CATALINA_HOME/bin/setclasspath.sh"
echo "This file is needed to run this program"
exit 1
fi
fi

# Add on extra jar files to CLASSPATH
if [ -n "$JSSE_HOME" ]; then
CLASSPATH="$CLASSPATH":"$JSSE_HOME"/lib/jcert.jar:"$JSSE_HOME"/lib/jnet.jar:"$JSSE_HOME"/lib/jsse.jar
fi
CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar:"$CATALINA_HOME"/bin/commons-logging-api.jar

if [ -z "$CATALINA_BASE" ] ; then
CATALINA_BASE="$CATALINA_HOME"
fi

if [ -z "$CATALINA_TMPDIR" ] ; then
# Define the java.io.tmpdir to use for Catalina
CATALINA_TMPDIR="$CATALINA_BASE"/temp
fi

# Bugzilla 37848: When no TTY is available, don't output to console
have_tty=0
if [ "`tty`" != "not a tty" ]; then
have_tty=1
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
JAVA_HOME=`cygpath --absolute --windows "$JAVA_HOME"`
JRE_HOME=`cygpath --absolute --windows "$JRE_HOME"`
CATALINA_HOME=`cygpath --absolute --windows "$CATALINA_HOME"`
CATALINA_BASE=`cygpath --absolute --windows "$CATALINA_BASE"`
CATALINA_TMPDIR=`cygpath --absolute --windows "$CATALINA_TMPDIR"`
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$JSSE_HOME" ] && JSSE_HOME=`cygpath --absolute --windows "$JSSE_HOME"`
JAVA_ENDORSED_DIRS=`cygpath --path --windows "$JAVA_ENDORSED_DIRS"`
fi

# Set juli LogManager if it is present
if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then
JAVA_OPTS="$JAVA_OPTS "-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager" "-Djava.util.logging.config.file="$CATALINA_BASE/conf/logging.properties"
fi

# ----- Execute The Requested Command -----------------------------------------

# Bugzilla 37848: only output this if we have a TTY
if [ $have_tty -eq 1 ]; then
echo "Using CATALINA_BASE: $CATALINA_BASE"
echo "Using CATALINA_HOME: $CATALINA_HOME"
echo "Using CATALINA_TMPDIR: $CATALINA_TMPDIR"
if [ "$1" = "debug" -o "$1" = "javac" ] ; then
echo "Using JAVA_HOME: $JAVA_HOME"
else
echo "Using JRE_HOME: $JRE_HOME"
fi
fi

if [ "$1" = "jpda" ] ; then
if [ -z "$JPDA_TRANSPORT" ]; then
JPDA_TRANSPORT="dt_socket"
fi
if [ -z "$JPDA_ADDRESS" ]; then
JPDA_ADDRESS="8000"
fi
if [ -z "$JPDA_SUSPEND" ]; then
JPDA_SUSPEND="n"
fi
if [ -z "$JPDA_OPTS" ]; then
JPDA_OPTS="-Xdebug -Xrunjdwp:transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND"
fi
CATALINA_OPTS="$CATALINA_OPTS $JPDA_OPTS"
shift
fi

if [ "$1" = "debug" ] ; then
if $os400; then
echo "Debug command not available on OS400"
exit 1
else
shift
if [ "$1" = "-security" ] ; then
echo "Using Security Manager"
shift
exec "$_RUNJDB" $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-sourcepath "$CATALINA_HOME"/../../java \
-Djava.security.manager \
-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" start
else
exec "$_RUNJDB" $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-sourcepath "$CATALINA_HOME"/../../java \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" start
fi
fi

elif [ "$1" = "run" ]; then

shift
if [ "$1" = "-security" ] ; then
echo "Using Security Manager"
shift
exec "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-Djava.security.manager \
-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" start
else
exec "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" start
fi

elif [ "$1" = "start" ] ; then

shift
touch "$CATALINA_BASE"/logs/catalina.out
if [ "$1" = "-security" ] ; then
echo "Using Security Manager"
shift
"$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-Djava.security.manager \
-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" start \
>> "$CATALINA_BASE"/logs/catalina.out 2>&1 &

if [ ! -z "$CATALINA_PID" ]; then
echo $! > $CATALINA_PID
fi
else
"$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" start \
>> "$CATALINA_BASE"/logs/catalina.out 2>&1 &

if [ ! -z "$CATALINA_PID" ]; then
echo $! > $CATALINA_PID
fi
fi

elif [ "$1" = "stop" ] ; then

shift
FORCE=0
if [ "$1" = "-force" ]; then
shift
FORCE=1
fi

"$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" stop

if [ $FORCE -eq 1 ]; then
if [ ! -z "$CATALINA_PID" ]; then
echo "Killing: `cat $CATALINA_PID`"
kill -9 `cat $CATALINA_PID`
else
echo "Kill failed: \$CATALINA_PID not set"
fi
fi

elif [ "$1" = "version" ] ; then

"$_RUNJAVA" \
-classpath "$CATALINA_HOME/lib/catalina.jar" \
org.apache.catalina.util.ServerInfo

else

echo "Usage: catalina.sh ( commands ... )"
echo "commands:"
if $os400; then
echo " debug Start Catalina in a debugger (not available on OS400)"
echo " debug -security Debug Catalina with a security manager (not available on OS400)"
else
echo " debug Start Catalina in a debugger"
echo " debug -security Debug Catalina with a security manager"
fi
echo " jpda start Start Catalina under JPDA debugger"
echo " run Start Catalina in the current window"
echo " run -security Start in the current window with security manager"
echo " start Start Catalina in a separate window"
echo " start -security Start in a separate window with security manager"
echo " stop Stop Catalina"
echo " stop -force Stop Catalina (followed by kill -KILL)"
echo " version What version of tomcat are you running?"
exit 1

fi

That is the current script. When I looked at the documentation you provided, it looks like I will need to add the RestartService and StopService into it by just copying the normal start and stop lines.

Krevnik
Feb 28, 2008, 11:28 AM
That is the current script. When I looked at the documentation you provided, it looks like I will need to add the RestartService and StopService into it by just copying the normal start and stop lines.

Don't edit that file directly. It will just make things more difficult for you in the long run.

It is easier to write a simple wrapper script that handles the incoming commands from launchd, and then in RestartService and StopService, you can call out to catalina.sh to actually restart or stop the service. It will also need to be able to start the service as well.

Ikyo
Feb 28, 2008, 11:40 AM
So something like this:

wrapper.sh
#!/bin/sh

. /etc/rc.common

# The start subroutine
StartService() {
/Library/Tomcat/Home/bin/catalina.sh start
}

# The stop subroutine
StopService() {
/Library/Tomcat/Home/bin/catalina.sh stop
sleep 10
/Library/Tomcat/Home/bin/catalina.sh stop -force
}

# The restart subroutine
RestartService() {
/Library/Tomcat/Home/bin/catalina.sh stop
sleep 10
/Library/Tomcat/Home/bin/catalina.sh start
}

RunService "$1"

Krevnik
Feb 28, 2008, 11:59 AM
So something like this:

wrapper.sh
#!/bin/sh

. /etc/rc.common

# The start subroutine
StartService() {
/Library/Tomcat/Home/bin/catalina.sh start
}

# The stop subroutine
StopService() {
/Library/Tomcat/Home/bin/catalina.sh stop
sleep 10
/Library/Tomcat/Home/bin/catalina.sh stop -force
}

# The restart subroutine
RestartService() {
/Library/Tomcat/Home/bin/catalina.sh stop
sleep 10
/Library/Tomcat/Home/bin/catalina.sh start
}

RunService "$1"


Something like that, yeah. :)

Ikyo
Feb 28, 2008, 12:02 PM
I tried to use that and it didn't start when I booted the machine. I had to run it manually from the command prompt. This is the only line I could find in the system.log:

Feb 28 12:10:25 Mac-Mini com.apple.launchd[1] (org.apache.tomcat.tomcat6[54]): Stray process with PGID equal to this dead job: PID 75 PPID 1 java

Krevnik
Feb 28, 2008, 12:23 PM
I tried to use that and it didn't start when I booted the machine. I had to run it manually from the command prompt.

Check the console logs, it should have spit out an error.

I haven't written a daemon script myself in awhile, so I can't tell you off-hand what might be wrong with it.

Ikyo
Feb 28, 2008, 12:40 PM
I don't believe this will work from the launchdaemon Library. It will see the wrapper as the process and see it completing out and the item not running. I believe that is why it is doing the run away process error.

jeremy.king
Feb 28, 2008, 01:55 PM
See pages 32/33

http://books.google.com/books?id=vJttHyVF0SUC&pg=PA33&lpg=PA33&dq=launchd+tomcat&source=web&ots=i_3wtTsLdZ&sig=nrZn7AoeJMB-2IXQj75UTqfVX44&hl=en

The key is the wait command.

Ikyo
Feb 28, 2008, 02:02 PM
I have changed my wrapper program to use the wait command, but I keep getting 'pid XXX is not a child of this shell'

Ikyo
Feb 28, 2008, 02:09 PM
Got it to work. You can not use start because it will fork the program. It has to be started as run.