#!/bin/sh ################################################################################## # # # universalJavaApplicationStub # # # # # # A shellscript 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 2014-10-12 # # @version 0.7.0 # # # # # ################################################################################## # # # # # The MIT License (MIT) # # # # Copyright (c) 2014 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. # # # ################################################################################## # # resolve symlinks ##################### 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 # set the directory abspath of the current shell script PROGDIR=`dirname "$PRG"` # # set files and folders ############################################ # the absolute path of the app package cd "$PROGDIR"/../../ AppPackageFolder=`pwd` # the base path of the app package cd .. 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 # # read Info.plist and extract JVM options ############################################ # read the program name from CFBundleName CFBundleName=`/usr/libexec/PlistBuddy -c "print :CFBundleName" "${InfoPlistFile}"` # read the icon file name CFBundleIconFile=`/usr/libexec/PlistBuddy -c "print :CFBundleIconFile" "${InfoPlistFile}"` # 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=$? # read Info.plist in Apple style if exit code returns 0 (true, :Java key is present) if [ $exitcode -eq 0 ]; then # read the Java WorkingDirectory JVMWorkDir=`/usr/libexec/PlistBuddy -c "print :Java:WorkingDirectory" "${InfoPlistFile}" 2> /dev/null | xargs` # set Working Directory based upon Plist info if [ "${JVMWorkDir}" == "\$JAVAROOT" ]; then WorkingDirectory="${AppleJavaFolder}" elif [ "${JVMWorkDir}" == "\$APP_PACKAGE" ]; then WorkingDirectory="${AppPackageFolder}" elif [ "${JVMWorkDir}" == "\$USER_HOME" ]; then WorkingDirectory="~" elif [[ ! -z ${JVMWorkDir} ]]; then WorkingDirectory="${JVMWorkDir}" else # AppPackageRoot is the standard WorkingDirectory when the script is started WorkingDirectory="${AppPackageRoot}" fi # set Java and Resources folder JavaFolder="${AppleJavaFolder}" ResourcesFolder="${AppleResourcesFolder}" APP_PACKAGE="${AppPackageFolder}" JAVAROOT="${AppleJavaFolder}" USER_HOME="`eval echo ~`" # read the MainClass name JVMMainClass=`/usr/libexec/PlistBuddy -c "print :Java:MainClass" "${InfoPlistFile}" 2> /dev/null` # read the JVM Options JVMOptions=`/usr/libexec/PlistBuddy -c "print :Java:Properties" "${InfoPlistFile}" 2> /dev/null | grep " =" | sed 's/^ */-D/g' | tr '\n' ' ' | sed 's/ */ /g' | sed 's/ = /=/g' | xargs` # read StartOnMainThread JVMStartOnMainThread=`/usr/libexec/PlistBuddy -c "print :Java:StartOnMainThread" "${InfoPlistFile}" 2> /dev/null` if [ "${JVMStartOnMainThread}" == "true" ]; then echo ${JVMStartOnMainThread} > ~/Desktop/test.txt JVMOptions+=" -XstartOnFirstThread" fi # read the ClassPath in either Array or String style JVMClassPath_RAW=`/usr/libexec/PlistBuddy -c "print :Java:ClassPath" "${InfoPlistFile}" 2> /dev/null` if [[ $JVMClassPath_RAW == *Array* ]] ; then JVMClassPath=.`/usr/libexec/PlistBuddy -c "print :Java:ClassPath" "${InfoPlistFile}" 2> /dev/null | grep " " | sed 's/^ */:/g' | tr -d '\n' | xargs` else JVMClassPath=${JVMClassPath_RAW} fi # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME JVMClassPath=`eval "echo ${JVMClassPath}"` # read the JVM Default Options JVMDefaultOptions=`/usr/libexec/PlistBuddy -c "print :Java:VMOptions" "${InfoPlistFile}" 2> /dev/null | xargs` # read the JVM Arguments JVMArguments=`/usr/libexec/PlistBuddy -c "print :Java:Arguments" "${InfoPlistFile}" 2> /dev/null | xargs` # read Info.plist in Oracle style else # set Working Directory and Java and Resources folder JavaFolder="${OracleJavaFolder}" ResourcesFolder="${OracleResourcesFolder}" WorkingDirectory="${AppPackageFolder}" APP_ROOT="${AppPackageFolder}" # read the MainClass name JVMMainClass=`/usr/libexec/PlistBuddy -c "print :JVMMainClassName" "${InfoPlistFile}" 2> /dev/null` # read the JVM Options JVMOptions=`/usr/libexec/PlistBuddy -c "print :JVMOptions" "${InfoPlistFile}" 2> /dev/null | grep " -" | tr -d '\n' | sed 's/ */ /g' | xargs` # replace occurances of $APP_ROOT with it's content JVMOptions=`eval "echo ${JVMOptions}"` JVMClassPath="${JavaFolder}/*" # read the JVM Default Options JVMDefaultOptions=`/usr/libexec/PlistBuddy -c "print :JVMDefaultOptions" "${InfoPlistFile}" 2> /dev/null | grep -o "\-.*" | tr -d '\n' | xargs` # read the JVM Arguments JVMArguments=`/usr/libexec/PlistBuddy -c "print :JVMArguments" "${InfoPlistFile}" 2> /dev/null | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/ */ /g' | xargs` # replace occurances of $APP_ROOT with it's content JVMArguments=`eval "echo ${JVMArguments}"` fi # # find installed Java versions ################################# # first check system variable "$JAVA_HOME" if [ -n "$JAVA_HOME" ] ; then JAVACMD="$JAVA_HOME/bin/java" # otherwise check "/usr/libexec/java_home" symlinks elif [ -x /usr/libexec/java_home ] && [ -d "`/usr/libexec/java_home 2> /dev/null`" ] ; then JAVACMD="`/usr/libexec/java_home 2> /dev/null`/bin/java" # otherwise check Java standard symlink (old Apple Java) elif [ -x /Library/Java/Home/bin/java ]; then JAVACMD="/Library/Java/Home/bin/java" # fallback: public JRE plugin (Oracle Java) elif [ -x "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java" ]; then JAVACMD="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java" else # fallback fallback: /usr/bin/java JAVACMD="/usr/bin/java" fi # # execute JAVA commandline #################################################### # enable drag&drop to the dock icon export CFProcessPath="$0" # change to Working Directory based upon Apple/Oracle Plist info cd "${WorkingDirectory}" # execute Java and set # - classpath # - dock icon # - application name # - JVM options # - JVM default options # - main class # - JVM arguments exec "$JAVACMD" \ -cp "${JVMClassPath}" \ -Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \ -Xdock:name="${CFBundleName}" \ ${JVMOptions:+$JVMOptions }\ ${JVMDefaultOptions:+$JVMDefaultOptions }\ ${JVMMainClass}\ ${JVMArguments:+ $JVMArguments}