Files
JIMRI/scripts/AppScriptTemplate
2026-06-17 14:00:51 +02:00

632 lines
22 KiB
Bash
Executable File

#! /bin/bash
#
# Script to start a JMRI @VERSION@ application.
#
# This script is used for both all POSIX operating systems including Linux
# and macOS / OS X application bundles.
#
# If a "jre" directory is found in the current working directory,
# it's assumed that contains a correct JRE or JDK which will be used
# regardless of the setting of ${JAVA_HOME}
#
# If you need to specify an option with spaces in it, escape the spaces with a
# leading backslash like "\ ".
#
# If you need to add any persistent Java options or persistent command line
# arguments, include them in the "default_options" statement in the file
# jmri.conf in the settings directory.
#
# The default location for the settings directory is:
# - macOS / OS X: ${HOME}/Library/Preferences/JMRI
# - all other: ${HOME}/.jmri
#
# The settings directory can be set to a non-standard location using the
# "--settingsdir=/path/to/my/settings" command line option (unlike all other
# options, this one cannot be set in the jmri.conf file, since it determines
# from where the jmri.conf file is read).
#
# If your serial ports are not in the default list, include the names in the
# command line argument --serial-ports separated by commas:
# --serial-ports=locobuffer,cmri
#
# You can run separate instances of the program with their own preferences
# if you
# - Provide the name of a configuration file as a parameter
# or
# - Copy and rename this script.
#
# If you rename the script to, for example, JmriNew, it will use
# "JmriNewConfig.properties" as it's configuration file. Note that configuration
# files only determine which profile to use, and if the profile selector should
# be shown at application launch.
#
# If you are getting X11 warnings about meta keys, uncomment the next line
# xprop -root -remove _MOTIF_DEFAULT_BINDINGS
#
# For more information, please see
# http://jmri.org/help/en/html/doc/Technical/StartUpScripts.shtml
# prevent the use of unbound variables
set -u
# display valid arguments
function usage() {
cat <<EOM
Usage: $( basename $0 ) [--help] [OPTIONS] [--] [ARGUMENTS]
-c CONFIG, --config=CONFIG Start JMRI with configuration CONFIG
--cp:a=CLASSPATH Append specified JARs to the classpath
Multiple JARs are separated with colons (:)
--cp:p=CLASSPATH Prepend specified JARs to the classpath
Multiple JARs are separated with colons (:)
-d, --debug Add verbose output to this script
-ea, -da, -enableassertions, -disableassertions Java assertions
-DPROPERTY Set the Java System property PROPERTY
-JOPTION Pass the option OPTION to the JVM
-m MAIN, --main=MAIN Use main() method in class MAIN to start JMRI
-p PROFILE, --profile=PROFILE Start JMRI with the profile PROFILE
--serial-ports=SERIAL_PORTS Use the serial ports in SERIAL_PORTS by name
Multiple names are separated with commas (,)
--settingsdir=SETTINGS_DIR Use SETTINGS_DIR as the settings directory
-T Running Jemmy tests, set options appropriately
-t Not running Jemmy tests, use regular menu options
-- Do not process anything following as an option,
even if it matches one of the above options
EOM
}
# parse passed in arguments from either default_options or command line
# except --settingsdir argument
function parse_args() {
while [ $# -gt 0 ] ; do
if [ -z "${1}" ] ; then
shift
continue
fi
# note: set DEBUG=yes in environment to see at this point
[ -n "${DEBUG}" ] && echo "Parsing Arg: '${1}'" | tee -a ${launcher_log}
case "${1}" in
# append to classpath
--cp:a) post_classpath="${post_classpath}:${2}" ; shift ;;
--cp:a=*) post_classpath="${post_classpath}:${1#*=}" ;;
# prepend to classpath
--cp:p) pre_classpath="${pre_classpath}:${2}" ; shift ;;
--cp:p=*) pre_classpath="${pre_classpath}:${1#*=}" ;;
# use named configuration
-c|--config) CONFIGNAME="${2}" ; shift ;;
--config=*) CONFIGNAME="${1#*=}" ;;
# Java system properties
-D*) jmri_options="${jmri_options} ${1}" ;;
# debugging
-d|--debug) DEBUG="yes" ;;
# help
--help) usage ; exit 2 ;;
# heap sizes
-J-Xms*) jmri_xms="${1#-J}" ;;
-J-Xmx*) jmri_xmx="${1#-J}" ;;
# JVM arguments other than max memory
-J*) jmri_options="${jmri_options} ${1#-J}" ;;
# assertions
-ea|-enableassertions) jmri_options="${jmri_options} ${1}" ;;
-da|-disableassertions) jmri_options="${jmri_options} ${1}" ;;
-ea:*|-enableassertions:*) jmri_options="${jmri_options} ${1}" ;;
-da:*|-disableassertions:*) jmri_options="${jmri_options} ${1}" ;;
# main class
-m|--main) CLASSNAME="${2}" ; shift ;;
--main=*) CLASSNAME="${1#*=}" ;;
# JMRI configuration profile
-p|--profile) jmri_options="${jmri_options} -Dorg.jmri.profile=${2}" ; shift ;;
--profile=*) jmri_options="${jmri_options} -Dorg.jmri.profile=${1#*=}" ;;
# serial ports
--serial-ports) JMRI_SERIAL_PORTS="${2}" ; shift ;;
--serial-ports=*) JMRI_SERIAL_PORTS="${1#*=}" ;;
# ignore and do not pass the settingsdir argument
--settingsdir) shift ;;
--settingsdir=*) ;;
# ignore and do not pass a ProcessSerialNumber argument (from the open command on macOS)
-psn_*) ;;
-T) JEMMY="yes" ;;
-t) JEMMY="" ;;
# everything after this is to be passed to JMRI
--) ARGS="${ARGS} $@" ; break ;;
# pass anything else on to JMRI
*) ARGS="${ARGS} ${1}" ;;
esac
shift
done
}
# Get the default heap size for JMRI in MB.
# Based on total memory size, this is:
# - 1/4 total memory size on systems with more than 4GB RAM with minimum of 2GB
# - 1/2 total memory size on systems with 1-4GB RAM with minimum of 768MB
# - 3/4 total memory size on systems with less than 1GB RAM
# - with an absolute minimum of 192MB
# - note that minimums are maximum allocation for immediately smaller RAM size
# (i.e. as 2GB = 1/2 4GB, do not use 1.5GB on 6GB system (1.5GB = 1/4 6GB))
function heap_size() {
# get Java heap size
heap=$( "${JAVACMD}" -XX:+PrintFlagsFinal -version 2>/dev/null | grep MaxHeapSize | grep -v SoftMaxHeapSize | awk '{print $4}' )
heap=$( expr ${heap} / 1048576 2>/dev/null ) # bytes to MB
# Java heap defaults to 1/4 total memory size
# if <= 768MB (1/4 of 3GB), set it ourselves
if [ -z "${heap}" ] || [ ${heap} -le 768 ] ; then
case "$( uname )" in
Linux*)
mem=$( cat /proc/meminfo | grep MemTotal | tr -d [:space:][:alpha:]: )
mem=$( expr $mem / 1024 )
;;
Darwin*)
mem=$( /usr/sbin/sysctl hw.memsize | tr -d [:alpha:][:space:].: )
mem=$( expr $mem / 1048576 )
;;
*)
;;
esac
if [ -z "$mem" ] ; then
mem=640
fi
if [ $mem -le 1024 ] ; then
heap=$( expr $mem \* 3 / 4 )
elif [ $mem -le 4096 ] ; then
heap=$( expr $mem \* 1 / 2 )
[ $heap -le 768 ] && heap=768 # 3/4 of 1024
else
heap=$( expr $mem \* 1 / 4 )
[ $heap -le 2048 ] && heap=2048 # 1/2 of 4096
fi
if [ $heap -lt 192 ] ; then
heap=192 # 3/4 of 256MB
fi
fi
echo $heap
return 0
}
# get the script's location as an absolute path
SCRIPTDIR=$(cd "$( dirname "${0}" )" && pwd)
# define the class to be invoked
DEFAULT_APP_NAME="@NAME@"
CLASSNAME="@CLASS@"
# define empty jmri_options
jmri_options=""
# define empty array of passed in options
declare -a all_options=()
# ensure JMRI environment options are always set
JMRI_OPTIONS=${JMRI_OPTIONS:-}
JMRI_SERIAL_PORTS=${JMRI_SERIAL_PORTS:-}
# set default config name
CONFIGNAME=""
CONFIGFILE=""
# Installation locations
JAVA_HOME=${JAVA_HOME:-}
JMRI_HOME=${JMRI_HOME:-}
BUNDLEDIR=""
# Set default arguments
ARGS=
# set DEBUG to any non-empty string to see debugging output
DEBUG=${DEBUG:-}
# set JEMMY to any non-empty string to configure for Jemmy testing
JEMMY=${JEMMY:-}
# set default classpaths additions
pre_classpath=""
post_classpath=""
# set the OS (can be overridden in environment for debugging and development)
# this value is used to find OS-specific libraries, so it gets normalized
# in following case statement
OS=${OS:-}
if [ -z "${OS}" ] ; then
OS=$( uname -s )
fi
# sanitize os names
case "${OS}" in
macosx|Darwin*)
OS="macosx"
;;
Linux*)
OS="linux"
;;
esac
ARCH=${ARCH:-}
settingsdir=${settingsdir:-}
# get the settings directory if set on command line
found_settingsdir=""
for opt in "$@"; do
if [ "${found_settingsdir}" = "yes" ]; then
# --settingsdir /path/to/... part 2
settingsdir="$opt"
jmri_options="${jmri_options} -Djmri.prefsdir=${settingsdir}"
break
elif [ "$opt" = "--settingsdir" ]; then
# --settingsdir /path/to/... part 1
found_settingsdir="yes"
elif [[ "$opt" =~ "--settingsdir=" ]]; then
# --settingsdir=/path/to/...
settingsdir="${opt#*=}"
jmri_options="${jmri_options} -Djmri.prefsdir=${settingsdir}"
break;
fi
done
if [ -z "$settingsdir" ]; then
# set OS-specific settingsdir if not on cmd line
case "${OS}" in
macosx|Darwin*)
settingsdir="${HOME}/Library/Preferences/JMRI"
;;
Linux*|*)
settingsdir="${HOME}/.jmri"
;;
esac
fi
# log to $settingsdir/log/launcher.log for debugging purposes
launcher_log=${settingsdir}/log/launcher.log
mkdir -p ${settingsdir}/log
[ -f ${launcher_log} ] && rm -f ${launcher_log}
# process arguments, stored arguments first, so CLI arguments can override
# process default_options from the launcher configuration file
if [ -f "${settingsdir}/jmri.conf" ] ; then
default_options=""
source "${settingsdir}/jmri.conf"
if [ -n "${default_options}" ] ; then
IFS=' ' read -a all_options <<< "${default_options}"
fi
fi
# process environment and command line arguments
if [ -n "${JMRI_OPTIONS}" ] ; then
IFS=' ' read -a options <<< "${JMRI_OPTIONS}"
for option in "${options[@]}" ; do
all_options=("${all_options[@]-}" "${option}")
done
fi
if [ $# -gt 0 ] ; then
for option in "$@"; do
all_options=("${all_options[@]-}" "${option}")
done
fi
parse_args "${all_options[@]:-}"
# define JMRI_HOME if it is not defined
if [ -z "${JMRI_HOME}" ] ; then
JMRI_HOME="${SCRIPTDIR}"
if [ "$OS" = "macosx" ] ; then
# on OS X, the default JMRI_HOME is the directory containing the .app bundle
BUNDLEDIR=$(cd "${SCRIPTDIR}/../.." && pwd)
if [ -f "${BUNDLEDIR}/Contents/MacOS/StartJMRI" ] ; then
JMRI_HOME=$(cd "${BUNDLEDIR}/.." && pwd)
DEBUG="yes" # default to on, so always available in Console.app
else
BUNDLEDIR=""
fi
fi
fi
cd "${JMRI_HOME}"
[ -n "${DEBUG}" ] && echo "PWD: '${PWD}'" | tee -a ${launcher_log}
# define JAVA_HOME if needed
[ -n "${DEBUG}" ] && echo "initial JAVA_HOME: '${JAVA_HOME}' OS: '${OS}'" | tee -a ${launcher_log}
# First, select local java version, if present; this overrides ${JAVA_HOME} passed in
if [ -d "${JMRI_HOME}/jre" ]; then
JAVA_HOME=${JMRI_HOME}/jre
PATH=${JAVA_HOME}/bin:$PATH
JAVACMD=java
if [ "$OS" = "macosx" ] ; then
# if macosx and xattr exists, use it
if type "xattr" > /dev/null ; then
xattr -r -d com.apple.quarantine ${JAVA_HOME}/bin/java || true
fi
fi
fi
# Otherwise, try to find an installed JRE
if [ -z "${JAVA_HOME}" ] ; then
#
# macOS / OS X get special treatment
# all others use which to find java
# otherwise error out
#
if [ "$OS" = "macosx" ] ; then
#
# macOS / OS X has a bewildering array of possibilities these days
#
# /usr/libexec/java_home will find the correct version, if a JDK for the
# required version or newer is installed.
#
# Look for the Oracle Java 11 JRE and use it if found
# Otherwise, use java_home if it's present
# Otherwise, prompt the user to install Java
#
JAVA_HOME="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home"
if [ -x "${JAVA_HOME}/bin/java" ] ; then
JAVACMD="${JAVA_HOME}/bin/java"
# Test if java is present and at least version 11
java_version="$( "${JAVACMD}" -version 2>&1 | grep version )"
[ -n "${DEBUG}" ] && echo "JAVA_HOME/bin/java: '${java_version}'" | tee -a ${launcher_log}
if [[ ! "${java_version}" =~ \"21|\"20|\"19|\"18|\"17|\"16|\"15|\"14|\"13|\"12|\"11|\"22|\"23|\"24|\"25|\"26|\"27|\"28|\"29 ]] ; then
JAVA_HOME=""
fi
else
# Reset JAVA_HOME since there is no java executable in it
JAVA_HOME=""
fi
# Find an installed JRE/JDK location; note search order
for jversion in 21 20 19 18 17 16 15 14 13 12 11 22 23 24 25 26 27 28 29; do
if [[ -z "${JAVA_HOME}" && -x /usr/libexec/java_home ]] ; then
# Test for any JDKs
[ -n "${DEBUG}" ] && echo "test for Java: '${jversion}'" | tee -a ${launcher_log}
JAVA_HOME=$( /usr/libexec/java_home --version ${jversion} --failfast 2>/dev/null )
if [ -n "${JAVA_HOME}" ] ; then
JAVACMD="${JAVA_HOME}/bin/java"
break
fi
fi
done
if [ -z "${JAVA_HOME}" ] ; then
# JAVA_HOME is still not defined, so prompt to install Java for OS X
/usr/bin/osascript << EOT
try
display alert "To use JMRI you must install a supported Java version, at least Java 11. Java 21 is recommended." \
message "Click \"More Info...\" to learn more about installing Java." \
buttons {"More Info...", "OK"} \
default button "OK" \
cancel button "More Info..."
on error number -128
-- user pressed cancel button
open location "https://www.jmri.org/java"
end try
EOT
exit 1
fi
elif which java >/dev/null 2>&1 ; then
JAVACMD=$( which java )
JAVA_HOME="$( dirname ${JAVACMD} )/.."
else
# we don't know that osascript is available here; macOS shouldn't reach here
echo "Please install Java 21 per your operating system vendor's instructions." | tee -a ${launcher_log}
exit 1
fi
else
JAVACMD="${JAVA_HOME}/bin/java"
if [ ! -x "${JAVACMD}" ] ; then
echo "Unable to execute java using JAVA_HOME=\"${JAVA_HOME}\"." | tee -a ${launcher_log}
exit 1
fi
fi
# make JAVA_HOME available to spawned processes
export JAVA_HOME
[ -n "${DEBUG}" ] && echo "JAVA_HOME: '${JAVA_HOME}'" | tee -a ${launcher_log}
[ -n "${DEBUG}" ] && echo "JAVACMD: '${JAVACMD}'" | tee -a ${launcher_log}
# set if -J-Xmx=... is not in options or arguments
if [ -z "${jmri_xmx:-}" ] ; then
jmri_xmx="-Xmx$( heap_size )m"
fi
# set if -J-Xms=... is not in options or arguments
if [ -z "${jmri_xms:-}" ] ; then
# initial heap size = default for 6 GB RAM (default = 1/64 installed RAM)
jmri_xms="-Xms96m"
fi
# permit Java 9 illegal access
if [[ $( "${JAVACMD}" -version 2>&1 | grep version ) =~ \"9 ]] ; then
jmri_options="${jmri_options} --illegal-access=warn"
fi
# build library path
SYSLIBPATH=
LIBDIR="lib"
if [ -d "${LIBDIR}/$OS" ] ; then
SYSLIBPATH="${LIBDIR}/$OS"
fi
# one or another of these commands should return a useful value, except that sometimes
# it is spelled funny (e,g, amd64, not x86_64).
if [ -z "$ARCH" ] ; then
for cmd in "arch" "uname -i" "uname -p" "uname -m" ; do
ARCH=$( $cmd 2>/dev/null )
if [ -n "$ARCH" ] ; then
# canonicalize the architecture names where possible
# we currently have AMD64 / X86_64
if [ "$ARCH" = "amd64" ] ; then
ARCH="x86_64"
fi
# and all the flavors of ia32 (traditional x86)
if [ "$ARCH" = "i686" -o "$ARCH" = "i586" -o "$ARCH" = "i486" ] ; then
ARCH="i386"
fi
# Now deal with ARM architecture:
# armv5 contains v5 soft-float version
# armv6l contains v6 hard-float version
# armv7l contains v7 hard-float version
# aarch64 contains 64-bit v8 version
if [ "${ARCH:0:3}" = "arm" ] ; then
#determine arm version & hard vs. soft float using readelf
if type "readelf" >& /dev/null; then
ARCHVERSION=$( readelf -A /proc/self/exe | grep Tag_CPU_arch | cut -d : -f2 )
if [ -z "$ARCHVERSION" -o "${ARCHVERSION:1:2}" = "v5" ] ; then
ARCH="armv5"
elif [ "${ARCHVERSION:1:2}" = "v6" ] ; then
ARCH="armv6l"
elif [ "${ARCHVERSION:1:2}" = "v7" ] ; then
ARCH="armv7l"
else
ARCH="armv5"
fi
fi
fi
if [ "$ARCH" = "aarch64" -o "$ARCH" = "arm64" ] ; then
ARCH="aarch64"
fi
if [ -d "${SYSLIBPATH}/$ARCH" ] ; then
SYSLIBPATH="${SYSLIBPATH}/$ARCH:$SYSLIBPATH"
# we're only interested in ONE of these values, so as soon as we find a supported
# architecture directory, continue processing and start up the program
break
fi
fi
done
fi
# build classpath dynamically
# add pre classpath
CP=""
if [ -n "${pre_classpath}" ] ; then
pre_classpath="${pre_classpath#:}"
CP="${pre_classpath}:"
fi
CP="${CP}.:classes:target/classes:jmri.jar"
# add contents of lib
CP="${CP}:$( ls -m ${LIBDIR}/*.jar | tr -d ' \n' | tr ',' ':' )"
# add contents of the user settings / lib directory, if anything
mkdir -p ${settingsdir}/lib
if [ ! -z "$(ls -A ${settingsdir}/lib)" ]; then
CP="${CP}:$( ls -m ${settingsdir}/lib/*.jar | tr -d ' \n' | tr ',' ':' )"
fi
# add post classpath
if [ -n "${post_classpath}" ] ; then
post_classpath="${post_classpath#:}"
CP="${CP}:${post_classpath}"
fi
# remove any "\ " escaped spaces, since these are needed for bash, but not java
CP="${CP//\\ / }"
[ -n "${DEBUG}" ] && echo "CLASSPATH: '${CP}'" | tee -a ${launcher_log}
[ -n "${DEBUG}" ] && echo "Java CMD: '${JAVACMD[@]}'" | tee -a ${launcher_log}
# configuration file name is 1st argument.
# If not provided, build config file name dynamically
if [ "$OS" = "macosx" -a -n "${BUNDLEDIR}" ] ; then
# OS X can have spaces in the application name
APPNAME=$( basename -s .app "${BUNDLEDIR}" )
else
APPNAME=$( basename "$0" )
fi
[ -n "${DEBUG}" ] && echo "APPNAME: '${APPNAME}'" | tee -a ${launcher_log}
# Process a config file name if passed as an option or when the application is
# NOT the default one this script was built for and pass it as a Java property
# so that scripts expecting another argument as the first one get that instead
if [ "$APPNAME" != "$DEFAULT_APP_NAME" -o -n "${CONFIGNAME}" ] ; then
if [ -z "${CONFIGNAME}" ] ; then
CONFIGNAME=$( echo $APPNAME | tr -d '[:space:]' | tr -d '=' )
fi
CONFIGFILE="-Dorg.jmri.Apps.configFilename=${CONFIGNAME}Config.xml"
[ -n "${DEBUG}" ] && echo "CONFIGFILE: '${CONFIGFILE}'" | tee -a ${launcher_log}
fi
# create the option string
#
# Add JVM and RMI options to user options, if any
if [ "$OS" = "macosx" ] ; then
# since bash mangles the application name and icon in $OPTIONS,
# these are not stored in $OPTIONS
OS_OPTIONS=""
# omit custom menu bar if running Jemmy tests
if [ "$JEMMY" = "" ] ; then
OS_OPTIONS="${OS_OPTIONS} -Dapple.laf.useScreenMenuBar=true"
OS_OPTIONS="${OS_OPTIONS} -Dcom.apple.macos.useScreenMenuBar=true"
fi
OS_OPTIONS="${OS_OPTIONS} -Dfile.encoding=UTF-8"
if [ -f "${BUNDLEDIR}/Contents/Resources/@ICON@.icns" ] ; then
APPICON="${BUNDLEDIR}/Contents/Resources/@ICON@.icns"
else
APPICON=$( find "${BUNDLEDIR}" 2>/dev/null | grep -s -m 1 icns )
fi
fi
OPTIONS="${jmri_options} -noverify"
OPTIONS="${OPTIONS} -Djava.security.policy=${LIBDIR}/security.policy"
OPTIONS="${OPTIONS} -Djava.rmi.server.codebase=file:target/classes/"
OPTIONS="${OPTIONS} -Djava.library.path=.:$SYSLIBPATH:${LIBDIR}"
OPTIONS="${OPTIONS} -Dnashorn.args=--no-deprecation-warning"
# the next is used by DarkLAF
OPTIONS="${OPTIONS} --add-exports java.desktop/sun.awt=ALL-UNNAMED"
# memory start and max limits
OPTIONS="${OPTIONS} ${OS_OPTIONS-} ${jmri_xms} ${jmri_xmx}"
[ -n "${DEBUG}" ] && echo "OPTIONS: '${OPTIONS}'" | tee -a ${launcher_log}
# handle ports in --settings argument or JMRI_SERIAL_PORTS environment variable
# but not if already in OPTIONS
ALTPORTS=
if [[ -n "${JMRI_SERIAL_PORTS}" && ! ${OPTIONS} =~ "-Dpurejavacomm.portnamepattern=" ]] ; then
ALTPORTS="-Dpurejavacomm.portnamepattern=${JMRI_SERIAL_PORTS}"
fi
declare -a DOCK_OPTIONS
# Apple dock extensions to java get mangled by bash if included in ${OPTIONS}
if [ "$OS" = "macosx" ] ; then
DOCK_OPTIONS=(-Xdock:name="${APPNAME}" -Xdock:icon="${APPICON}")
[ -n "${DEBUG}" ] && echo "DOCK_OPTIONS: '${DOCK_OPTIONS[@]}'" | tee -a ${launcher_log}
fi
# check java version >= 11 and inform user if not
"${JAVACMD}" ${OPTIONS} ${ALTPORTS} ${CONFIGFILE} -cp lib/JavaVersionCheckWindow.jar apps.JavaVersionCheckWindow
EXIT_STATUS=$?
if [ $EXIT_STATUS -ne 0 ] ; then
exit $EXIT_STATUS
fi
RESTART_CODE=100
EXIT_STATUS=${RESTART_CODE}
while [ "${EXIT_STATUS}" -eq "${RESTART_CODE}" ] ; do
trap 'kill -TERM $PID' TERM INT
trap 'kill -HUP $PID' HUP
if [ "$OS" = "macosx" ] ; then
"${JAVACMD}" "${DOCK_OPTIONS[@]}" ${OPTIONS} ${ALTPORTS} ${CONFIGFILE} -cp "${CP}" "${CLASSNAME}" ${ARGS} &
PID=$!
else
"${JAVACMD}" ${OPTIONS} ${ALTPORTS} ${CONFIGFILE} -cp "${CP}" "${CLASSNAME}" ${ARGS} &
PID=$!
fi
wait $PID
trap - TERM INT HUP
wait $PID
EXIT_STATUS=$?
[ -n "${DEBUG}" ] && echo Exit Status: "${EXIT_STATUS}" | tee -a ${launcher_log}
done
if [ $EXIT_STATUS -eq 200 ] ; then
sudo shutdown -h now
fi
if [ $EXIT_STATUS -eq 210 ] ; then
sudo shutdown -r now
fi
exit $EXIT_STATUS