Skip to content

Instantly share code, notes, and snippets.

@nabsha
Last active May 27, 2020 23:16
Show Gist options
  • Save nabsha/3ad4e058ed6de59804e391927b5e33ad to your computer and use it in GitHub Desktop.
Save nabsha/3ad4e058ed6de59804e391927b5e33ad to your computer and use it in GitHub Desktop.
This is the updated mule wrapper script for 3.9.x standalone enterprise to run on MacOS catalina
#! /bin/sh
# Copyright (c) 1999, 2013 Tanuki Software, Ltd.
#
# Java Service Wrapper sh script. Suitable for starting and stopping
# wrapped Java applications on UNIX platforms.
# Get the fully qualified path to the script
case $0 in
/*)
SCRIPT="$0"
;;
*)
PWD=`pwd`
SCRIPT="$PWD/$0"
;;
esac
# Resolve the true real path without any sym links.
CHANGED=true
while [ "X$CHANGED" != "X" ]
do
# Change spaces to ":" so the tokens can be parsed.
SAFESCRIPT=`echo $SCRIPT | sed -e 's; ;:;g'`
# Get the real path to this script, resolving any symbolic links
TOKENS=`echo $SAFESCRIPT | sed -e 's;/; ;g'`
REALPATH=
for C in $TOKENS; do
# Change any ":" in the token back to a space.
C=`echo $C | sed -e 's;:; ;g'`
REALPATH="$REALPATH/$C"
# If REALPATH is a sym link, resolve it. Loop for nested links.
while [ -h "$REALPATH" ] ; do
LS="`ls -ld "$REALPATH"`"
LINK="`expr "$LS" : '.*-> \(.*\)$'`"
if expr "$LINK" : '/.*' > /dev/null; then
# LINK is absolute.
REALPATH="$LINK"
else
# LINK is relative.
REALPATH="`dirname "$REALPATH"`""/$LINK"
fi
done
done
if [ "$REALPATH" = "$SCRIPT" ]
then
CHANGED=""
else
SCRIPT="$REALPATH"
fi
done
# Save the startup directory
STARTUP_DIR=`pwd`
# Change the current directory to the location of the script
cd "`dirname "$REALPATH"`"
REALDIR=`pwd`
######################################################################
# Customized for Mule
######################################################################
# Check for MULE_HOME
if [ -z "$MULE_HOME" ] ; then
# REALDIR points to $MULE_HOME/bin now, strip off the bin part so
# we get a proper MULE_HOME instead of a relative path
MULE_HOME="`dirname "${REALDIR}"`"
fi
# strip a potential trailing slash in MULE_HOME. This is required to build a
# valid path for WRAPPER_CMD below which is used when running the stop
# command
MULE_HOME=`echo ${MULE_HOME} | sed -e 's/\/$//'`
export MULE_HOME
echo "MULE_HOME is set to ${MULE_HOME}"
# If MULE_BASE is not set, set it to MULE_HOME
if [ -z "$MULE_BASE" ] ; then
MULE_BASE=$MULE_HOME
fi
export MULE_BASE
# Application
if [ "$MULE_APP" = "" ]
then
MULE_APP="mule_ee"
fi
export MULE_APP
if [ "$MULE_APP_LONG" = "" ]
then
MULE_APP_LONG="Mule Enterprise Edition"
fi
export MULE_APP_LONG
APP_NAME=${MULE_APP}
APP_LONG_NAME=${MULE_APP_LONG}
# Wrapper
WRAPPER_CMD="${MULE_HOME}/lib/boot/exec/wrapper"
WRAPPER_CONF="${MULE_BASE}/conf/wrapper.conf"
# redirect JUL logs to log4j2
JUL_LOG_MANAGER=-M-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
MULE_OPTS="wrapper.working.dir=\"$STARTUP_DIR\" \
wrapper.app.parameter.1=$2 \
wrapper.app.parameter.2=$3 \
wrapper.app.parameter.3=$4 \
wrapper.app.parameter.4=$5 \
wrapper.app.parameter.5=$6 \
wrapper.app.parameter.6=$7 \
wrapper.app.parameter.7=$8 \
wrapper.app.parameter.8=$9 \
wrapper.app.parameter.9=$10"
# Configure remote Java debugging options here
# Setting suspend=y will wait for you to connect before proceeding
JPDA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
######################################################################
# Priority at which to run the wrapper. See "man nice" for valid priorities.
# nice is only used if a priority is specified.
PRIORITY=
# Location of the pid file.
PIDDIR="."
# If uncommented, causes the Wrapper to be shutdown using an anchor file.
# When launched with the 'start' command, it will also ignore all INT and
# TERM signals.
#IGNORE_SIGNALS=true
# If specified, the Wrapper will be run as the specified user.
# IMPORTANT - Make sure that the user has the required privileges to write
# the PID file and wrapper.log files. Failure to be able to write the log
# file will cause the Wrapper to exit without any way to write out an error
# message.
# NOTE - This will set the user which is used to run the Wrapper as well as
# the JVM and is not useful in situations where a privileged resource or
# port needs to be allocated prior to the user being changed.
#RUN_AS_USER=
# The following two lines are used by the chkconfig command. Change as is
# appropriate for your application. They should remain commented.
# chkconfig: 2345 20 80
# description: Mule
#-----------------------------------------------------------------------------
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MULE_HOME/lib/native/profiler
# If the PIDDIR is relative, set its value relative to the full REALPATH to avoid problems if
# the working directory is later changed.
FIRST_CHAR=`echo $PIDDIR | cut -c1,1`
if [ "$FIRST_CHAR" != "/" ]
then
PIDDIR=$REALDIR/$PIDDIR
fi
# Same test for WRAPPER_CMD
FIRST_CHAR=`echo $WRAPPER_CMD | cut -c1,1`
if [ "$FIRST_CHAR" != "/" ]
then
WRAPPER_CMD=$REALDIR/$WRAPPER_CMD
fi
# Same test for WRAPPER_CONF
FIRST_CHAR=`echo $WRAPPER_CONF | cut -c1,1`
if [ "$FIRST_CHAR" != "/" ]
then
WRAPPER_CONF=$REALDIR/$WRAPPER_CONF
fi
# Process ID
ANCHORFILE="$PIDDIR/$APP_NAME.anchor"
######################################################################
# Patched for Mule
######################################################################
PIDFILE="$PIDDIR/.$APP_NAME.pid"
######################################################################
LOCKDIR="/var/lock/subsys"
LOCKFILE="$LOCKDIR/$APP_NAME"
pid=""
# Resolve the location of the 'ps' command
PSEXE="/usr/ucb/ps"
if [ ! -x "$PSEXE" ]
then
PSEXE="/usr/bin/ps"
if [ ! -x "$PSEXE" ]
then
PSEXE="/bin/ps"
if [ ! -x "$PSEXE" ]
then
echo "Unable to locate 'ps'."
echo "Please report this message along with the location of the command on your system."
exit 1
fi
fi
fi
PSKEYWORD="args"
# Resolve the os
DIST_OS=`uname -s | tr [:upper:] [:lower:] | tr -d [:blank:]`
case "$DIST_OS" in
'sunos')
DIST_OS="solaris"
;;
'hp-ux' | 'hp-ux64')
DIST_OS="hpux"
;;
'darwin')
DIST_OS="macosx"
PSKEYWORD="command"
;;
'unix_sv')
DIST_OS="unixware"
;;
'aix')
DIST_OS="aix"
;;
esac
# Compare Versions $1<$2=0, $1==$2=1, $1>$2=2
compareVersions () {
if [ "$1" = "$2" ]
then
return 1
else
local i=1
while true
do
local v1=`echo "$1" | cut -d '.' -f $i`
local v2=`echo "$2" | cut -d '.' -f $i`
if [ "X$v1" = "X" ]
then
if [ "X$v2" = "X" ]
then
return 1
fi
v1="0"
elif [ "X$v2" = "X" ]
then
v2="0"
fi
if [ $v1 -lt $v2 ]
then
return 0
elif [ $v1 -gt $v2 ]
then
return 2
fi
i=`expr $i + 1`
done
fi
}
######################################################################
# Patched for Mule (MULE-1288, MULE-1322, MULE-1337, MULE-1396)
######################################################################
# Resolve the architecture
if [ "$DIST_OS" = "macosx" ]
then
OS_VER=`sw_vers | grep 'ProductVersion:' | grep -o '[0-9]*\.[0-9]*\.[0-9]*\|[0-9]*\.[0-9]*'`
DIST_ARCH="universal"
compareVersions "$OS_VER" "10.5.0"
if [ $? -lt 1 ]
then
DIST_BITS="32"
KEY_KEEP_ALIVE="OnDemand"
else
# Note: "OnDemand" has been deprecated and replaced from Mac OS X 10.5 by "KeepAlive"
KEY_KEEP_ALIVE="KeepAlive"
if [ "X`/usr/sbin/sysctl -n hw.cpu64bit_capable`" = "X1" ]
then
DIST_BITS="64"
else
DIST_BITS="32"
fi
fi
APP_PLIST_BASE=${PLIST_DOMAIN}.${APP_NAME}
APP_PLIST=${APP_PLIST_BASE}.plist
else
UNAME_PROC_OPTION="-m"
# The previous approach was this:
# If a 32-bit wrapper binary exists then it will work on 32 or 64 bit
# platforms, if the 64-bit binary exists then the distribution most
# likely wants to use long names.
DIST_BITS="32"
# Handling the AIX peculiarities
# For more info on how to determine whether the kernel is 32 or 64-bit see http://www-01.ibm.com/support/docview.wss?uid=swg21256116
if [ "$DIST_OS" = "aix" ]; then
UNAME_PROC_OPTION="-p"
DIST_BITS=`getconf KERNEL_BITMODE`
fi
PROC_ARCH=`uname $UNAME_PROC_OPTION | tr [:upper:] [:lower:] | tr -d [:blank:]`
case "$PROC_ARCH" in
'amd64' | 'athlon' | 'i386' | 'i486' | 'i586' | 'i686')
DIST_ARCH="x86"
;;
'x86_64')
DIST_ARCH="x86"
# on 64 bit Linuxes the 32 bit subsystem may not be installed so
# let's use the 64 bit wrapper
DIST_BITS="64"
;;
'ia32' | 'ia64')
DIST_ARCH="ia"
;;
'ip27')
DIST_ARCH="mips"
;;
'ppc64le')
DIST_ARCH="ppc64le"
DIST_BITS="64"
;;
'power' | 'powerpc' | 'power_pc' | 'ppc64' | 'powermacintosh')
DIST_ARCH="ppc"
;;
'pa_risc' | 'pa-risc')
DIST_ARCH="parisc"
;;
'i86pc')
DIST_ARCH="x86"
DIST_BITS=`isainfo -b`
;;
'sun4u' | 'sun4us' | 'sun4v' | 'sparcv9' | 'sparc')
DIST_ARCH="sparc"
DIST_BITS=`isainfo -b`
;;
'9000/800')
DIST_ARCH="parisc"
;;
's390x')
DIST_ARCH="390"
DIST_BITS=`getconf LONG_BIT`
;;
armv*)
if [ -z "`readelf -A /proc/self/exe | grep Tag_ABI_VFP_args`" ] ; then
DIST_ARCH="armel"
DIST_BITS="32"
else
echo "Warning: An armhf architecture has been detected and this is not currently supported. The armel version of the wrapper will be used instead."
DIST_ARCH="armel"
DIST_BITS="32"
fi
;;
*)
echo "Your machine's hardware type (uname $UNAME_PROC_OPTION) was not recognized by the Service Wrapper as a supported platform."
echo "Please report this message along with your machine's processor/architecture."
exit 1
;;
esac
fi
######################################################################
outputFile() {
if [ -f "$1" ]
then
echo " $1 (Found but not executable.)";
else
echo " $1"
fi
}
WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-$DIST_BITS"
if [ -x "$WRAPPER_TEST_CMD" ]
then
WRAPPER_CMD="$WRAPPER_TEST_CMD"
else
if [ "$DIST_OS" = "macosx" ]
then
WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-universal-32"
if [ -x "$WRAPPER_TEST_CMD" ]
then
WRAPPER_CMD="$WRAPPER_TEST_CMD"
else
WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
if [ -x "$WRAPPER_TEST_CMD" ]
then
WRAPPER_CMD="$WRAPPER_TEST_CMD"
else
WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-universal-64"
if [ -x "$WRAPPER_TEST_CMD" ]
then
WRAPPER_CMD="$WRAPPER_TEST_CMD"
else
if [ ! -x "$WRAPPER_CMD" ]
then
echo "Unable to locate any of the following binaries:"
outputFile "$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32"
outputFile "$WRAPPER_CMD-$DIST_OS-universal-32"
outputFile "$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
outputFile "$WRAPPER_CMD-$DIST_OS-universal-64"
outputFile "$WRAPPER_CMD"
exit 1
fi
fi
fi
fi
else
if [ ! -x "$WRAPPER_CMD" ]
then
echo "Unable to locate any of the following binaries:"
outputFile "$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32"
outputFile "$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-64"
outputFile "$WRAPPER_CMD"
exit 1
fi
fi
fi
# Build the nice clause
if [ "X$PRIORITY" = "X" ]
then
CMDNICE=""
else
CMDNICE="nice -$PRIORITY"
fi
# Build the anchor file clause.
if [ "X$IGNORE_SIGNALS" = "X" ]
then
ANCHORPROP=
IGNOREPROP=
else
ANCHORPROP=wrapper.anchorfile=\"$ANCHORFILE\"
IGNOREPROP=wrapper.ignore_signals=TRUE
fi
# Build the lock file clause. Only create a lock file if the lock directory exists on this platform.
LOCKPROP=
if [ -d $LOCKDIR ]
then
if [ -w $LOCKDIR ]
then
LOCKPROP=wrapper.lockfile=\"$LOCKFILE\"
fi
fi
checkUser() {
# $1 touchLock flag
# $2, $3, etc complete command line received
# Check the configured user. If necessary rerun this script as the desired user.
if [ "X$RUN_AS_USER" != "X" ]
then
# Resolve the location of the 'id' command
IDEXE="/usr/xpg4/bin/id"
if [ ! -x "$IDEXE" ]
then
IDEXE="/usr/bin/id"
if [ ! -x "$IDEXE" ]
then
echo "Unable to locate 'id'."
echo "Please report this message along with the location of the command on your system."
exit 1
fi
fi
if [ "`$IDEXE -u -n`" = "$RUN_AS_USER" ]
then
# Already running as the configured user. Avoid password prompts by not calling su.
RUN_AS_USER=""
fi
fi
if [ "X$RUN_AS_USER" != "X" ]
then
# If LOCKPROP and $RUN_AS_USER are defined then the new user will most likely not be
# able to create the lock file. The Wrapper will be able to update this file once it
# is created but will not be able to delete it on shutdown. If $1 is defined then
# the lock file should be created for the current command
if [ "X$LOCKPROP" != "X" ]
then
if [ "X$1" != "X" ]
then
# Resolve the primary group
RUN_AS_GROUP=`groups $RUN_AS_USER | awk '{print $3}' | tail -1`
if [ "X$RUN_AS_GROUP" = "X" ]
then
RUN_AS_GROUP=$RUN_AS_USER
fi
touch $LOCKFILE
chown $RUN_AS_USER:$RUN_AS_GROUP $LOCKFILE
fi
fi
# Still want to change users, recurse. This means that the user will only be
# prompted for a password once. Variables shifted by 1 in order to remove the touchLock flag.
shift
RELAUNCH_CMD="$REALPATH $@"
su -m $RUN_AS_USER -c "$RELAUNCH_CMD"
# Now that we are the original user again, we may need to clean up the lock file.
if [ "X$LOCKPROP" != "X" ]
then
getpid
if [ "X$pid" = "X" ]
then
# Wrapper is not running so make sure the lock file is deleted.
if [ -f "$LOCKFILE" ]
then
rm "$LOCKFILE"
fi
fi
fi
exit 0
fi
}
getpid() {
if [ -f "$PIDFILE" ]
then
if [ -r "$PIDFILE" ]
then
pid=`cat "$PIDFILE"`
if [ "X$pid" != "X" ]
then
# It is possible that 'a' process with the pid exists but that it is not the
# correct process. This can happen in a number of cases, but the most
# common is during system startup after an unclean shutdown.
# The ps statement below looks for the specific wrapper command running as
# the pid. If it is not found then the pid file is considered to be stale.
######################################################################
# TODO MULE-2052: ps -o args gets truncated to 80 columns on Solaris which makes
# this test fail if the path is too long.
# http://sourceforge.net/tracker/index.php?func=detail&aid=1664303&group_id=39428&atid=425187
######################################################################
if [ "$DIST_OS" = 'solaris' ]
then
# on Solaris, both /usr/ucb/ps and /usr/bin/ps accept the ww option.
# Use it to overcome the truncation issue mentioned above
pidtest=`$PSEXE ww $pid | grep "$WRAPPER_CMD" | tail -1`
else
pidtest=`$PSEXE -p $pid -o $PSKEYWORD | grep "$WRAPPER_CMD" | tail -1`
fi
if [ "X$pidtest" = "X" ]
then
# This is a stale pid file.
rm -f "$PIDFILE"
echo "Removed stale pid file: $PIDFILE"
pid=""
fi
fi
else
echo "Cannot read $PIDFILE."
exit 1
fi
fi
}
testpid() {
if [ "$DIST_OS" = 'solaris' ]
then
# on Solaris, both /usr/ucb/ps and /usr/bin/ps accept the ww option.
pid=`$PSEXE ww $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1`
else
pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1`
fi
if [ "X$pid" = "X" ]
then
# Process is gone so remove the pid file.
rm -f "$PIDFILE"
pid=""
fi
}
console() {
echo "Running $APP_LONG_NAME..."
getpid
if [ "X$pid" = "X" ]
then
# The string passed to eval must handle spaces in paths correctly.
COMMAND_LINE="$CMDNICE \"$WRAPPER_CMD\" \"$WRAPPER_CONF\" wrapper.syslog.ident=$APP_NAME wrapper.pidfile=\"$PIDFILE\" $ANCHORPROP $LOCKPROP"
######################################################################
# Customized for Mule
######################################################################
eval $COMMAND_LINE $MULE_OPTS
######################################################################
else
echo "$APP_LONG_NAME is already running."
exit 1
fi
}
start() {
echo "Starting $APP_LONG_NAME..."
getpid
if [ "X$pid" = "X" ]
then
# The string passed to eval must handles spaces in paths correctly.
COMMAND_LINE="$CMDNICE \"$WRAPPER_CMD\" \"$WRAPPER_CONF\" wrapper.syslog.ident=$APP_NAME wrapper.pidfile=\"$PIDFILE\" wrapper.daemonize=TRUE $ANCHORPROP $IGNOREPROP $LOCKPROP"
######################################################################
# Customized for Mule
######################################################################
eval $COMMAND_LINE $MULE_OPTS
######################################################################
else
echo "$APP_LONG_NAME is already running."
exit 1
fi
}
stopit() {
echo "Stopping $APP_LONG_NAME..."
getpid
if [ "X$pid" = "X" ]
then
echo "$APP_LONG_NAME was not running."
else
if [ "X$IGNORE_SIGNALS" = "X" ]
then
# Running so try to stop it.
kill $pid
if [ $? -ne 0 ]
then
# An explanation for the failure should have been given
echo "Unable to stop $APP_LONG_NAME."
exit 1
fi
else
rm -f "$ANCHORFILE"
if [ -f "$ANCHORFILE" ]
then
# An explanation for the failure should have been given
echo "Unable to stop $APP_LONG_NAME."
exit 1
fi
fi
# We can not predict how long it will take for the wrapper to
# actually stop as it depends on settings in wrapper.conf.
# Loop until it does.
savepid=$pid
CNT=0
TOTCNT=0
while [ "X$pid" != "X" ]
do
# Show a waiting message every 5 seconds.
if [ "$CNT" -lt "5" ]
then
CNT=`expr $CNT + 1`
else
echo "Waiting for $APP_LONG_NAME to exit..."
CNT=0
fi
TOTCNT=`expr $TOTCNT + 1`
sleep 1
testpid
done
pid=$savepid
testpid
if [ "X$pid" != "X" ]
then
echo "Failed to stop $APP_LONG_NAME."
exit 1
else
echo "Stopped $APP_LONG_NAME."
fi
fi
}
status() {
getpid
if [ "X$pid" = "X" ]
then
echo "$APP_LONG_NAME is not running."
exit 1
else
echo "$APP_LONG_NAME is running ($pid)."
exit 0
fi
}
dump() {
echo "Dumping $APP_LONG_NAME..."
getpid
if [ "X$pid" = "X" ]
then
echo "$APP_LONG_NAME was not running."
else
kill -3 $pid
if [ $? -ne 0 ]
then
echo "Failed to dump $APP_LONG_NAME."
exit 1
else
echo "Dumped $APP_LONG_NAME."
fi
fi
}
checkAdditionalJvmParams() {
# The string passed to eval must handle spaces in paths correctly.
"$MULE_HOME/bin/launcher" \"$MULE_HOME/bin/additional.groovy\" \"$WRAPPER_CONF\" \"$JPDA_OPTS\" \"$JUL_LOG_MANAGER\" $@
EXIT_STATUS=$?
if [ "$EXIT_STATUS" -ne "0" ] ; then
exit $EXIT_STATUS
fi
}
case "$1" in
'console')
checkUser touchlock $*
checkAdditionalJvmParams $*
console
;;
'start')
checkUser touchlock $*
checkAdditionalJvmParams $*
start
;;
'stop')
checkUser "" $*
stopit
;;
'restart')
checkUser touchlock $*
stopit
start
;;
'status')
checkUser "" $*
status
;;
'dump')
checkUser "" $*
dump
;;
*)
######################################################################
# Customized for Mule
######################################################################
echo "Running in console (foreground) mode by default, use Ctrl-C to exit..."
# Change back to the original startup directory.
cd "$STARTUP_DIR"
# Call this script recursively with the "console" parameter.
"$REALPATH" console $*
######################################################################
;;
esac
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment