diff --git a/packaging_utils/JavaApplicationStub b/packaging_utils/JavaApplicationStub index d28a69c58..ede56f977 100644 --- a/packaging_utils/JavaApplicationStub +++ b/packaging_utils/JavaApplicationStub @@ -13,8 +13,8 @@ # # # @author Tobias Fischer # # @url https://github.com/tofi86/universalJavaApplicationStub # -# @date 2014-10-12 # -# @version 0.7.0 # +# @date 2015-11-02 # +# @version 1.0.1 # # # # # ################################################################################## @@ -22,7 +22,7 @@ # # # The MIT License (MIT) # # # -# Copyright (c) 2014 Tobias Fischer # +# Copyright (c) 2015 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 # @@ -49,7 +49,7 @@ # # resolve symlinks -##################### +############################################ PRG=$0 @@ -100,11 +100,12 @@ InfoPlistFile="${AppPackageFolder}"/Contents/Info.plist JVMVersion="" + + # # read Info.plist and extract JVM options ############################################ - # read the program name from CFBundleName CFBundleName=`/usr/libexec/PlistBuddy -c "print :CFBundleName" "${InfoPlistFile}"` @@ -115,59 +116,64 @@ CFBundleIconFile=`/usr/libexec/PlistBuddy -c "print :CFBundleIconFile" "${InfoPl # 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" -# read Info.plist in Apple style if exit code returns 0 (true, :Java key is present) -if [ $exitcode -eq 0 ]; then +# 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 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}" +# read Info.plist in Apple style if exit code returns 0 (true, :Java key is present) +if [ $exitcode -eq 0 ]; then - elif [ "${JVMWorkDir}" == "\$APP_PACKAGE" ]; then - WorkingDirectory="${AppPackageFolder}" + # set Java and Resources folder + JavaFolder="${AppleJavaFolder}" + ResourcesFolder="${AppleResourcesFolder}" - elif [ "${JVMWorkDir}" == "\$USER_HOME" ]; then - WorkingDirectory=~ + APP_PACKAGE="${AppPackageFolder}" + JAVAROOT="${AppleJavaFolder}" + USER_HOME="$HOME" - elif [[ "${JVMWorkDir}" =~ "\$APP_PACKAGE" ]]; then - WorkingDirectory="${AppPackageFolder}"$(sed 's|\$APP_PACKAGE||g' <<< ${JVMWorkDir}) - elif [[ ! -z ${JVMWorkDir} ]]; then + # read the Java WorkingDirectory + JVMWorkDir=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:WorkingDirectory" "${InfoPlistFile}" 2> /dev/null | xargs` + + # set Working Directory based upon Plist info + if [[ ! -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}" + # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME + WorkingDirectory=`eval "echo ${WorkingDirectory}"` - 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` + JVMMainClass=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:MainClass" "${InfoPlistFile}" 2> /dev/null` + + # read the SplashFile name + JVMSplashFile=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:SplashFile" "${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` + JVMOptions=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:Properties" "${InfoPlistFile}" 2> /dev/null | grep " =" | sed 's/^ */-D/g' | tr '\n' ' ' | sed 's/ */ /g' | sed 's/ = /=/g' | xargs` + # replace occurences of $APP_ROOT with its content + JVMOptions=`eval "echo ${JVMOptions}"` # read StartOnMainThread - JVMStartOnMainThread=`/usr/libexec/PlistBuddy -c "print :Java:StartOnMainThread" "${InfoPlistFile}" 2> /dev/null` + JVMStartOnMainThread=`/usr/libexec/PlistBuddy -c "print ${JavaKey}: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` + JVMClassPath_RAW=`/usr/libexec/PlistBuddy -c "print ${JavaKey}: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` + JVMClassPath=.`/usr/libexec/PlistBuddy -c "print ${JavaKey}:ClassPath" "${InfoPlistFile}" 2> /dev/null | grep " " | sed 's/^ */:/g' | tr -d '\n' | xargs` else JVMClassPath=${JVMClassPath_RAW} fi @@ -175,17 +181,15 @@ if [ $exitcode -eq 0 ]; then JVMClassPath=`eval "echo ${JVMClassPath}"` # read the JVM Default Options - JVMDefaultOptions=`/usr/libexec/PlistBuddy -c "print :Java:VMOptions" "${InfoPlistFile}" 2> /dev/null | xargs` + JVMDefaultOptions=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:VMOptions" "${InfoPlistFile}" 2> /dev/null | xargs` # read the JVM Arguments - JVMArguments=`/usr/libexec/PlistBuddy -c "print :Java:Arguments" "${InfoPlistFile}" 2> /dev/null | xargs` + JVMArguments=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:Arguments" "${InfoPlistFile}" 2> /dev/null | xargs` + # replace occurences of $APP_ROOT with its content + JVMArguments=`eval "echo ${JVMArguments}"` # read the Java version we want to find - JVMVersion=`/usr/libexec/PlistBuddy -c "print :Java:JVMVersion" "${InfoPlistFile}" 2> /dev/null | xargs` - if [ "${JVMVersion}" != "" ]; then - JVMVersion="-v "${JVMVersion} - fi - + JVMVersion=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:JVMVersion" "${InfoPlistFile}" 2> /dev/null | xargs` # read Info.plist in Oracle style else @@ -200,44 +204,139 @@ else # read the MainClass name JVMMainClass=`/usr/libexec/PlistBuddy -c "print :JVMMainClassName" "${InfoPlistFile}" 2> /dev/null` + # read the SplashFile name + JVMSplashFile=`/usr/libexec/PlistBuddy -c "print :JVMSplashFile" "${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 + # replace occurences of $APP_ROOT with its content JVMOptions=`eval "echo ${JVMOptions}"` - JVMClassPath="${JavaFolder}/*" + # read the ClassPath in either Array or String style + JVMClassPath_RAW=`/usr/libexec/PlistBuddy -c "print JVMClassPath" "${InfoPlistFile}" 2> /dev/null` + if [[ $JVMClassPath_RAW == *Array* ]] ; then + JVMClassPath=.`/usr/libexec/PlistBuddy -c "print JVMClassPath" "${InfoPlistFile}" 2> /dev/null | grep " " | sed 's/^ */:/g' | tr -d '\n' | xargs` + elif [[ ! -z ${JVMClassPath_RAW} ]] ; then + JVMClassPath=${JVMClassPath_RAW} + else + #default: fallback to OracleJavaFolder + JVMClassPath="${JavaFolder}/*" + fi + # expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME + JVMClassPath=`eval "echo ${JVMClassPath}"` # read the JVM Default Options - JVMDefaultOptions=`/usr/libexec/PlistBuddy -c "print :JVMDefaultOptions" "${InfoPlistFile}" 2> /dev/null | grep -o "\-.*" | tr -d '\n' | xargs` + 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 + # replace occurences of $APP_ROOT with its content JVMArguments=`eval "echo ${JVMArguments}"` fi +# +# function: Java version tester +############################################ + +function JavaVersionSatisfiesRequirement() { + java_ver=$1 + java_req=$2 + + # e.g. 1.8* + if [[ ${java_req} =~ ^[0-9]\.[0-9]\*$ ]] ; then + java_req_num=${java_req:0:3} + java_ver_num=${java_ver:0:3} + if [ ${java_ver_num} == ${java_req_num} ] ; then + return 0 + else + return 1 + fi + + # e.g. 1.8+ + elif [[ ${java_req} =~ ^[0-9]\.[0-9]\+$ ]] ; then + java_req_num=`echo ${java_req} | sed -E 's/[[:punct:]]//g'` + java_ver_num=`echo ${java_ver} | sed -E 's/[[:punct:]]//g'` + if [ ${java_ver_num} -ge ${java_req_num} ] ; then + return 0 + else + return 1 + fi + + # e.g. 1.8 + elif [[ ${java_req} =~ ^[0-9]\.[0-9]$ ]] ; then + if [ ${java_ver} == ${java_req} ] ; then + return 0 + else + return 1 + fi + + # not matching any of the above patterns + else + return 2 + fi +} + + +# +# function: extract Java major version +# from java -version command +############################################ + +function extractJavaMajorVersion() { + echo `"$1" -version 2>&1 | awk '/version/{print $NF}' | sed -E 's/"([0-9.]{3})[0-9_.]{5}"/\1/g'` +} + + + # # find installed Java versions -################################# +############################################ + +apple_jre_plugin="/Library/Java/Home/bin/java" +apple_jre_version=`extractJavaMajorVersion "${apple_jre_plugin}"` +oracle_jre_plugin="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java" +oracle_jre_version=`extractJavaMajorVersion "${oracle_jre_plugin}"` # first check system variable "$JAVA_HOME" if [ -n "$JAVA_HOME" ] ; then JAVACMD="$JAVA_HOME/bin/java" + +# check for JVMversion requirements +elif [ ! -z ${JVMVersion} ] ; then + + # first in "/usr/libexec/java_home" symlinks + if [ -x /usr/libexec/java_home ] && /usr/libexec/java_home -F -v ${JVMVersion} > /dev/null ; then + JAVACMD="`/usr/libexec/java_home -F -v ${JVMVersion} 2> /dev/null`/bin/java" + + # then in Oracle JRE plugin + elif [ -x "${oracle_jre_plugin}" ] && JavaVersionSatisfiesRequirement ${oracle_jre_version} ${JVMVersion} ; then + JAVACMD="${oracle_jre_plugin}" + + # then in Apple JRE plugin + elif [ -x "${apple_jre_plugin}" ] && JavaVersionSatisfiesRequirement ${apple_jre_version} ${JVMVersion} ; then + JAVACMD="${apple_jre_plugin}" + + else + # display error message with applescript + osascript -e "tell application \"System Events\" to display dialog \"ERROR launching '${CFBundleName}'\n\nNo suitable Java version found on your system!\nThis program requires Java ${JVMVersion}\nMake sure you install the required Java version.\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" + # exit with error + exit 3 + fi # otherwise check "/usr/libexec/java_home" symlinks -elif [ -x /usr/libexec/java_home ] && [ -d "`/usr/libexec/java_home ${JVMVersion} 2> /dev/null`" ] ; then - JAVACMD="`/usr/libexec/java_home ${JVMVersion} 2> /dev/null`/bin/java" +elif [ -x /usr/libexec/java_home ] && /usr/libexec/java_home -F > /dev/null; then + JAVACMD="`/usr/libexec/java_home 2> /dev/null`/bin/java" -# otherwise check Java standard symlink (old Apple Java) +# otherwise check Java standard symlink (old Apple JRE) elif [ -h /Library/Java/Home ]; then - JAVACMD="/Library/Java/Home/bin/java" + JAVACMD="${apple_jre_plugin}" # fallback: public JRE plugin (Oracle Java) else - JAVACMD="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java" + JAVACMD="${oracle_jre_plugin}" fi # fallback fallback: /usr/bin/java @@ -255,7 +354,7 @@ if [ -z ${JVMMainClass} ]; then # display error message with applescript osascript -e "tell application \"System Events\" to display dialog \"ERROR launching '${CFBundleName}'!\n\n'MainClass' isn't specified!\nJava application cannot be started!\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" # exit with error - exit 1 + exit 2 # check whether $JAVACMD is a file and executable @@ -277,6 +376,7 @@ elif [ -f "$JAVACMD" ] && [ -x "$JAVACMD" ] ; then # - JVM arguments exec "$JAVACMD" \ -cp "${JVMClassPath}" \ + -splash:"${ResourcesFolder}/${JVMSplashFile}" \ -Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \ -Xdock:name="${CFBundleName}" \ ${JVMOptions:+$JVMOptions }\ @@ -288,11 +388,10 @@ elif [ -f "$JAVACMD" ] && [ -x "$JAVACMD" ] ; then else # display error message with applescript - osascript -e "tell application \"System Events\" to display dialog \"ERROR launching '${CFBundleName}'!\n\nYou need to have JAVA installed on your Mac!\nVisit http://java.com for more information...\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" - - # and open java.com - open http://java.com + osascript -e "tell application \"System Events\" to display dialog \"ERROR launching '${CFBundleName}'!\n\nYou need to have JAVA installed on your Mac!\nVisit java.com for installation instructions...\" with title \"${CFBundleName}\" buttons {\"Later\", \"Visit java.com\"} default button \"Visit java.com\" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)" \ + -e "set response to button returned of the result" \ + -e "if response is \"Visit java.com\" then open location \"http://java.com\"" # exit with error exit 1 -fi \ No newline at end of file +fi diff --git a/packaging_utils/MegaMekLab.app/Contents/Info.plist b/packaging_utils/MegaMekLab.app/Contents/Info.plist index 69cac1622..e73058901 100644 --- a/packaging_utils/MegaMekLab.app/Contents/Info.plist +++ b/packaging_utils/MegaMekLab.app/Contents/Info.plist @@ -21,12 +21,12 @@ ???? CFBundleIconFile megameklab.icns - Java + JavaX MainClass megameklab.com.MegaMekLab JVMVersion - 1.7+ + 1.8+ ClassPath $JAVAROOT/../../../../MekHQ.app/Contents/Resources/Java/MegaMekLab.jar