#!/bin/bash
##################################################################################
# #
# universalJavaApplicationStub #
# #
# A BASH based JavaApplicationStub for Java Apps on Mac OS X #
# that works with both Apple's and Oracle's plist format. #
# #
# Inspired by Ian Roberts stackoverflow answer #
# at http://stackoverflow.com/a/17546508/1128689 #
# #
# @author Tobias Fischer #
# @url https://github.com/tofi86/universalJavaApplicationStub #
# @date 2023-02-04 #
# @version 3.3.0 #
# #
##################################################################################
# #
# The MIT License (MIT) #
# #
# Copyright (c) 2014-2023 Tobias Fischer #
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy #
# of this software and associated documentation files (the "Software"), to deal #
# in the Software without restriction, including without limitation the rights #
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #
# copies of the Software, and to permit persons to whom the Software is #
# furnished to do so, subject to the following conditions: #
# #
# The above copyright notice and this permission notice shall be included in all #
# copies or substantial portions of the Software. #
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
# SOFTWARE. #
# #
##################################################################################
# function 'stub_logger()'
#
# A logger which logs to the macOS Console.app using the 'syslog' command
#
# @param1 the log message
# @return void
################################################################################
function stub_logger() {
syslog -s -k \
Facility com.apple.console \
Level Notice \
Sender "$(basename "$0")" \
Message "[$$][${CFBundleName:-$(basename "$0")}] $1"
}
# set the directory abspath of the current
# shell script with symlinks being resolved
############################################
PRG=$0
while [ -h "$PRG" ]; do
ls=$(ls -ld "$PRG")
link=$(expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null)
if expr "$link" : '^/' 2> /dev/null >/dev/null; then
PRG="$link"
else
PRG="$(dirname "$PRG")/$link"
fi
done
PROGDIR=$(dirname "$PRG")
stub_logger "[StubDir] $PROGDIR"
# set files and folders
############################################
# the absolute path of the app package
cd "$PROGDIR"/../../ || exit 11
AppPackageFolder=$(pwd)
# the base path of the app package
cd .. || exit 12
AppPackageRoot=$(pwd)
# set Apple's Java folder
AppleJavaFolder="${AppPackageFolder}"/Contents/Resources/Java
# set Apple's Resources folder
AppleResourcesFolder="${AppPackageFolder}"/Contents/Resources
# set Oracle's Java folder
OracleJavaFolder="${AppPackageFolder}"/Contents/Java
# set Oracle's Resources folder
OracleResourcesFolder="${AppPackageFolder}"/Contents/Resources
# set path to Info.plist in bundle
InfoPlistFile="${AppPackageFolder}"/Contents/Info.plist
# set the default JVM Version to a null string
JVMVersion=""
JVMMaxVersion=""
# function 'plist_get()'
#
# read a specific Plist key with 'PlistBuddy' utility
#
# @param1 the Plist key with leading colon ':'
# @return the value as String or Array
################################################################################
plist_get(){
/usr/libexec/PlistBuddy -c "print $1" "${InfoPlistFile}" 2> /dev/null
}
# function 'plist_get_java()'
#
# read a specific Plist key with 'PlistBuddy' utility
# in the 'Java' or 'JavaX' dictionary (<dict>)
#
# @param1 the Plist :Java(X):Key with leading colon ':'
# @return the value as String or Array
################################################################################
plist_get_java(){
plist_get ${JavaKey:-":Java"}$1
}
# read Info.plist and extract JVM options
############################################
# read the program name from CFBundleName
CFBundleName=$(plist_get ':CFBundleName')
# read the icon file name
CFBundleIconFile=$(plist_get ':CFBundleIconFile')
# check Info.plist for Apple style Java keys -> if key :Java is present, parse in apple mode
/usr/libexec/PlistBuddy -c "print :Java" "${InfoPlistFile}" > /dev/null 2>&1
exitcode=$?
JavaKey=":Java"
# if no :Java key is present, check Info.plist for universalJavaApplication style JavaX keys -> if key :JavaX is present, parse in apple mode
if [ $exitcode -ne 0 ]; then
/usr/libexec/PlistBuddy -c "print :JavaX" "${InfoPlistFile}" > /dev/null 2>&1
exitcode=$?
JavaKey=":JavaX"
fi
# read 'Info.plist' file in Apple style if exit code returns 0 (true, ':Java' key is present)
if [ $exitcode -eq 0 ]; then
stub_logger "[PlistStyle] Apple"
# set Java and Resources folder
JavaFolder="${AppleJavaFolder}"
ResourcesFolder="${AppleResourcesFolder}"
# set expandable variables
APP_ROOT="${AppPackageFolder}"
APP_PACKAGE="${AppPackageFolder}"
JAVAROOT="${AppleJavaFolder}"
USER_HOME="$HOME"
# read the Java WorkingDirectory
JVMWorkDir=$(plist_get_java ':WorkingDirectory' | xargs)
# set Working Directory based upon PList value
if [[ ! -z ${JVMWorkDir} ]]; then
WorkingDirectory="${JVMWorkDir}"
else
# AppPackageRoot is the standard WorkingDirectory when the script is started
WorkingDirectory="${AppPackageRoot}"
fi
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
WorkingDirectory=$(eval echo "${WorkingDirectory}")
# read the MainClass name
JVMMainClass="$(plist_get_java ':MainClass')"
# read the SplashFile name
JVMSplashFile=$(plist_get_java ':SplashFile')
# read the JVM Properties as an array and retain spaces
IFS=$'\t\n'
JVMOptions=($(xargs -n1 <<<$(plist_get_java ':Properties' | grep " =" | sed 's/^ */-D/g' | sed -E 's/ = (.*)$/="\1"/g')))
unset IFS
# post processing of the array follows further below...
# read the ClassPath in either Array or String style
JVMClassPath_RAW=$(plist_get_java ':ClassPath' | xargs)
if [[ $JVMClassPath_RAW == *Array* ]] ; then
JVMClassPath=.$(plist_get_java ':ClassPath' | grep " " | sed 's/^ */:/g' | tr -d '\n' | xargs)
else
JVMClassPath=${JVMClassPath_RAW}
fi
# expand variables $APP_PACKAGE, $APP