mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2024-12-21 17:29:55 +00:00
mac: Use universalJavaApplicationStub
Here's a (very rough) implementation of a macBundle task using the universalJavaApplicationStub and jarbundler. Jarbundler's support files (ant build system and docs) are suffering bitrot, and I don't grok maven yet, so I'm really flying blind with it, so basically I'm committing it in a "baseline" working (if ugly) state. So ... _why_ use this? The old way of bundling Java apps doesn't work anymore. It tells you to get Apple's (compromised/unsafe) Java 6 and when you do it throws an error because your code compiled on Oracle JDK 8/9 won't run on it anymore. You're supposed to duplicate the JRE in each Java program you bundle as you would a private/custom framework. Yes, really. This solves the dependency issues at the cost of heavy resource waste. Except every new JDK generation changes HOW you do that, and the current method is totally proprietary to Oracle's JDK. For cross-platform development, it is NOT fun. So there's uJAS, which is literally a complex shell script to magically do the equivalent of typing java -jar <your program> from the command line—which does work BTW if all your dependencies are properly in your default classpath, etc. There used to be a couple of application bundler options, but the one that still works (only with uJAS if you have the most recent JDKs), is jarbundler. TODO: Clean this up, restore original functionality (zipball), include the commandline jar, etc. committing it in this state is that jarbundler's repo is a bit of a mess. The current version (and the version we need) is 3.3.0, the "latest" from 2015. The docs, examples, and the ant build system are all literally bitrotting from version 2.x, and do not work without some fixes. So in other words, I'm committing this in a state that I got to work so that if I screw it up, since I'm flying blind, I'll have a messy but working fallback. Okay, so _why_ use any of this at all? If you create an ACBuild.properties file and run ant, you can get AppleCommander.app to build, but it won't run. It tells you that you need to download Apple's legacy Java 6 which is neither safe nor supported anymore. If you install this, it will still give you an error because the generated code can't run under Java 6. What you're supposed to do now is bundle your JRE with every Java application bundle, which means multiple copies of libs on disk and in memory. Yes, really. Except Oracle keeps changing how you do this with each new JDK generation, and the current way is pretty much totally proprietary so that you're locked in to Oracle's JDK and couldn't use OpenJDK or something if that were an option. That's what universalJavaApplicationStub resolves—it builds an app bundle that uses whatever JDK/JRE you have installed from 6 onwards. And it in turn needs jarbundler or something like it. Except all of the "something like it" solutions are dead or deprecated save the latest release of jarbundler which was modified to support uJAS and then promptly left more or less untouched since. But it "works".
This commit is contained in:
parent
752cdc91b6
commit
2e2a34e77e
@ -29,6 +29,10 @@
|
||||
<available file="${keyconf}" property="keyconf-exists" />
|
||||
</condition>
|
||||
|
||||
<taskdef name="jarbundler"
|
||||
classname="com.ultramixer.jarbundler.JarBundler"
|
||||
classpath="mac/jarbundler-core-3.3.0.jar" />
|
||||
|
||||
<target name="version" description="Get version from source.">
|
||||
<property name="main.path" value="src/com/webcodepro/applecommander/ui"/>
|
||||
<loadfile srcfile="${main.path}/AppleCommander.java" property="acVersion">
|
||||
@ -128,21 +132,43 @@
|
||||
|
||||
<target name="macBundle" depends="init,jars" description="Build Mac application bundle.">
|
||||
<property name="mac.dir" value="mac"/>
|
||||
<!--
|
||||
<property name="mac.app" value="${mac.dir}/AppleCommander.app"/>
|
||||
<property name="mac.Contents" value="${mac.app}/Contents"/>
|
||||
<property name="mac.Java" value="${mac.Contents}/Resources/Java"/>
|
||||
-->
|
||||
<!--
|
||||
<copy file="${mac.dir}/Info.plist" todir="${mac.Contents}" overwrite="true">
|
||||
<filterset>
|
||||
<filter token="version" value="${acVersion}"/>
|
||||
</filterset>
|
||||
</copy>
|
||||
-->
|
||||
<jarbundler dir="${dist}" verbose="true" showPlist="true"
|
||||
name="AppleCommander"
|
||||
mainclass="com.webcodepro.applecommander.ui.AppleCommander"
|
||||
bundleid="com.webcodepro.applecommander"
|
||||
jar="${dist}/AppleCommander-${acVersion}.jar"
|
||||
version="${acVersion}" build="${acVersion}"
|
||||
stubfile="mac/universalJavaApplicationStub"
|
||||
icon="mac/AppleCommander.app/Contents/Resources/AppleCommander.icns"
|
||||
useJavaXKey="true"
|
||||
developmentregion="English"
|
||||
copyright="Copyright 2002-2008 Rob Greene and John B. Matthews."
|
||||
jvmversion="1.4*"
|
||||
/>
|
||||
|
||||
<!--
|
||||
<copy file="${guijar}" tofile="${mac.Java}/AppleCommander.jar"/>
|
||||
<copy file="${cmdjar}" tofile="${user.home}/bin/ac.jar"/>
|
||||
-->
|
||||
<!--
|
||||
<zip destfile="${maczip}">
|
||||
<zipfileset dir="${mac.app}" prefix="AppleCommander.app"/>
|
||||
<zipfileset dir="${mac.app}" prefix="AppleCommander.app"
|
||||
includes="Contents/MacOS/JavaApplicationStub" filemode="755"/>
|
||||
</zip>
|
||||
-->
|
||||
</target>
|
||||
|
||||
<target name="sourceZip" depends="init" description="Build source ZIP archive">
|
||||
|
BIN
mac/jarbundler-core-3.3.0.jar
Normal file
BIN
mac/jarbundler-core-3.3.0.jar
Normal file
Binary file not shown.
535
mac/universalJavaApplicationStub
Executable file
535
mac/universalJavaApplicationStub
Executable file
@ -0,0 +1,535 @@
|
||||
#!/bin/bash
|
||||
##################################################################################
|
||||
# #
|
||||
# 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 2017-07-28 #
|
||||
# @version 2.1.0 #
|
||||
# #
|
||||
# #
|
||||
##################################################################################
|
||||
# #
|
||||
# #
|
||||
# The MIT License (MIT) #
|
||||
# #
|
||||
# Copyright (c) 2017 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
|
||||
|
||||
# set the default JVM Version to a null string
|
||||
JVMVersion=""
|
||||
|
||||
|
||||
|
||||
#
|
||||
# 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=$?
|
||||
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 in Apple style if exit code returns 0 (true, :Java key is present)
|
||||
if [ $exitcode -eq 0 ]; then
|
||||
|
||||
# set Java and Resources folder
|
||||
JavaFolder="${AppleJavaFolder}"
|
||||
ResourcesFolder="${AppleResourcesFolder}"
|
||||
|
||||
APP_PACKAGE="${AppPackageFolder}"
|
||||
JAVAROOT="${AppleJavaFolder}"
|
||||
USER_HOME="$HOME"
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
|
||||
WorkingDirectory=`eval "echo ${WorkingDirectory}"`
|
||||
|
||||
|
||||
# read the MainClass name
|
||||
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 ${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 ${JavaKey}:StartOnMainThread" "${InfoPlistFile}" 2> /dev/null`
|
||||
if [ "${JVMStartOnMainThread}" == "true" ]; then
|
||||
JVMOptions+=" -XstartOnFirstThread"
|
||||
fi
|
||||
|
||||
# read the ClassPath in either Array or String style
|
||||
JVMClassPath_RAW=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:ClassPath" "${InfoPlistFile}" 2> /dev/null`
|
||||
if [[ $JVMClassPath_RAW == *Array* ]] ; then
|
||||
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
|
||||
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
|
||||
JVMClassPath=`eval "echo ${JVMClassPath}"`
|
||||
|
||||
# read the JVM Default Options in either Array or String style
|
||||
JVMDefaultOptions_RAW=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:VMOptions" "${InfoPlistFile}" 2> /dev/null | xargs`
|
||||
if [[ $JVMDefaultOptions_RAW == *Array* ]] ; then
|
||||
JVMDefaultOptions=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:VMOptions" "${InfoPlistFile}" 2> /dev/null | grep " " | sed 's/^ */ /g' | tr -d '\n' | xargs`
|
||||
else
|
||||
JVMDefaultOptions=${JVMDefaultOptions_RAW}
|
||||
fi
|
||||
|
||||
# read the JVM Arguments
|
||||
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 ${JavaKey}:JVMVersion" "${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="${OracleJavaFolder}"
|
||||
|
||||
APP_ROOT="${AppPackageFolder}"
|
||||
|
||||
# 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 occurences of $APP_ROOT with its content
|
||||
JVMOptions=`eval "echo ${JVMOptions}"`
|
||||
|
||||
# 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`
|
||||
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
|
||||
JVMClassPath=`eval "echo ${JVMClassPath}"`
|
||||
|
||||
elif [[ ! -z ${JVMClassPath_RAW} ]] ; then
|
||||
JVMClassPath=${JVMClassPath_RAW}
|
||||
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
|
||||
JVMClassPath=`eval "echo ${JVMClassPath}"`
|
||||
|
||||
else
|
||||
#default: fallback to OracleJavaFolder
|
||||
JVMClassPath="${JavaFolder}/*"
|
||||
# Do NOT expand the default App.app/Contents/Java/* classpath (#42)
|
||||
fi
|
||||
|
||||
# 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 occurences of $APP_ROOT with its content
|
||||
JVMArguments=`eval "echo ${JVMArguments}"`
|
||||
fi
|
||||
|
||||
|
||||
|
||||
#
|
||||
# internationalized messages
|
||||
#
|
||||
############################################
|
||||
|
||||
LANG=`defaults read -g AppleLocale`
|
||||
|
||||
# French localization
|
||||
if [[ $LANG == fr* ]] ; then
|
||||
MSG_ERROR_LAUNCHING="Erreur au lancement de '${CFBundleName}'."
|
||||
MSG_MISSING_MAINCLASS="'MainClass' n'est pas spécifié.\nL'application Java ne peut pas être lancée."
|
||||
MSG_NO_SUITABLE_JAVA="La version de Java installée sur votre système ne convient pas.\nCe programme nécessite Java"
|
||||
MSG_JAVA_VERSION_OR_LATER="ou ultérieur"
|
||||
MSG_JAVA_VERSION_LATEST="(dernière mise à jour)"
|
||||
MSG_NO_SUITABLE_JAVA_CHECK="Merci de bien vouloir installer la version de Java requise."
|
||||
MSG_INSTALL_JAVA="Java doit être installé sur votre système.\nRendez-vous sur java.com et suivez les instructions d'installation..."
|
||||
MSG_LATER="Plus tard"
|
||||
MSG_VISIT_JAVA_DOT_COM="Visiter java.com"
|
||||
|
||||
# German localization
|
||||
elif [[ $LANG == de* ]] ; then
|
||||
MSG_ERROR_LAUNCHING="FEHLER beim Starten von '${CFBundleName}'."
|
||||
MSG_MISSING_MAINCLASS="Die 'MainClass' ist nicht spezifiziert!\nDie Java-Anwendung kann nicht gestartet werden!"
|
||||
MSG_NO_SUITABLE_JAVA="Es wurde keine passende Java-Version auf Ihrem System gefunden!\nDieses Programm benötigt Java"
|
||||
MSG_JAVA_VERSION_OR_LATER="oder neuer"
|
||||
MSG_JAVA_VERSION_LATEST="(neuste Unterversion)"
|
||||
MSG_NO_SUITABLE_JAVA_CHECK="Stellen Sie sicher, dass die angeforderte Java-Version installiert ist."
|
||||
MSG_INSTALL_JAVA="Auf Ihrem System muss die 'Java'-Software installiert sein.\nBesuchen Sie java.com für weitere Installationshinweise."
|
||||
MSG_LATER="Später"
|
||||
MSG_VISIT_JAVA_DOT_COM="java.com öffnen"
|
||||
|
||||
# English default localization
|
||||
else
|
||||
MSG_ERROR_LAUNCHING="ERROR launching '${CFBundleName}'."
|
||||
MSG_MISSING_MAINCLASS="'MainClass' isn't specified!\nJava application cannot be started!"
|
||||
MSG_NO_SUITABLE_JAVA="No suitable Java version found on your system!\nThis program requires Java"
|
||||
MSG_JAVA_VERSION_OR_LATER="or later"
|
||||
MSG_JAVA_VERSION_LATEST="(latest update)"
|
||||
MSG_NO_SUITABLE_JAVA_CHECK="Make sure you install the required Java version."
|
||||
MSG_INSTALL_JAVA="You need to have JAVA installed on your Mac!\nVisit java.com for installation instructions..."
|
||||
MSG_LATER="Later"
|
||||
MSG_VISIT_JAVA_DOT_COM="Visit java.com"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# helper function:
|
||||
# extract Java version string from `java -version` command
|
||||
# works for both old (1.8) and new (9) version schema
|
||||
##########################################################
|
||||
function extractJavaVersionString() {
|
||||
# second sed command strips " and -ea from the version string
|
||||
echo `"$1" -version 2>&1 | awk '/version/{print $NF}' | sed -E 's/"//g;s/-ea//g'`
|
||||
}
|
||||
|
||||
|
||||
# helper function:
|
||||
# extract Java major version from java version string
|
||||
# - input '1.7.0_76' returns '7'
|
||||
# - input '1.8.0_121' returns '8'
|
||||
# - input '9-ea' returns '9'
|
||||
# - input '9.0.3' returns '9'
|
||||
##########################################################
|
||||
function extractJavaMajorVersion() {
|
||||
java_ver=$1
|
||||
# Java 6, 7, 8 starts with 1.x
|
||||
if [ ${java_ver:0:2} == "1." ] ; then
|
||||
echo ${java_ver} | sed -E 's/1\.([0-9])[0-9_.]{2,6}/\1/g'
|
||||
else
|
||||
# Java 9+ starts with x using semver versioning
|
||||
echo ${java_ver} | sed -E 's/([0-9]+)(-ea|(\.[0-9]+)*)/\1/g'
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# helper function:
|
||||
# return comparable version for java version string
|
||||
# basically just strip punctuation and leading '1.'
|
||||
##########################################################
|
||||
function comparableJavaVersionNumber() {
|
||||
echo $1 | sed -E 's/^1\.//g;s/[[:punct:]]//g'
|
||||
}
|
||||
|
||||
|
||||
# function:
|
||||
# Java version tester checks whether a given java version
|
||||
# satisfies the given requirement
|
||||
# - parameter1: the java major version (6, 7, 8, 9, etc.)
|
||||
# - parameter2: the java requirement (1.6, 1.7+, etc.)
|
||||
# - return: 0 (satiesfies), 1 (does not), 2 (error)
|
||||
##########################################################
|
||||
function JavaVersionSatisfiesRequirement() {
|
||||
java_ver=$1
|
||||
java_req=$2
|
||||
|
||||
# matches requirements with * modifier
|
||||
# e.g. 1.8*, 9*, 9.1*, 9.2.4*, 10*, 10.1*, 10.1.35*
|
||||
if [[ ${java_req} =~ ^[0-9]+(\.[0-9]+)*\*$ ]] ; then
|
||||
# remove last char (*) from requirement string for comparison
|
||||
java_req_num=${java_req::${#java_req}-1}
|
||||
if [ ${java_ver} == ${java_req_num} ] ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
# matches requirements with + modifier
|
||||
# e.g. 1.8+, 9+, 9.1+, 9.2.4+, 10+, 10.1+, 10.1.35+
|
||||
elif [[ ${java_req} =~ ^[0-9]+(\.[0-9]+)*\+$ ]] ; then
|
||||
java_req_num=$(comparableJavaVersionNumber ${java_req})
|
||||
java_ver_num=$(comparableJavaVersionNumber ${java_ver})
|
||||
if [ ${java_ver_num} -ge ${java_req_num} ] ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
# matches standard requirements without modifier
|
||||
# e.g. 1.8, 9, 9.1, 9.2.4, 10, 10.1, 10.1.35
|
||||
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
|
||||
# results in an error
|
||||
else
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
#
|
||||
# find installed Java versions
|
||||
############################################
|
||||
|
||||
apple_jre_plugin="/Library/Java/Home/bin/java"
|
||||
apple_jre_version=$(extractJavaMajorVersion $(extractJavaVersionString "${apple_jre_plugin}"))
|
||||
oracle_jre_plugin="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java"
|
||||
oracle_jre_version=$(extractJavaMajorVersion $(extractJavaVersionString "${oracle_jre_plugin}"))
|
||||
|
||||
# first check system variable "$JAVA_HOME"
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
|
||||
# PR 26: Allow specifying "$JAVA_HOME" relative to "$AppPackageFolder"
|
||||
# which allows for bundling a custom version of Java inside your app!
|
||||
if [[ $JAVA_HOME == /* ]] ; then
|
||||
# if "$JAVA_HOME" starts with a Slash it's an absolute path
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
else
|
||||
# otherwise it's a relative path to "$AppPackageFolder"
|
||||
JAVACMD="$AppPackageFolder/$JAVA_HOME/bin/java"
|
||||
fi
|
||||
|
||||
# check for a specific Java version, specified in JVMversion Plist key
|
||||
elif [ ! -z ${JVMVersion} ] ; then
|
||||
|
||||
# first check "/usr/libexec/java_home" symlinks
|
||||
if [ -x /usr/libexec/java_home ] && /usr/libexec/java_home -F -v ${JVMVersion} > /dev/null 2>&1 ; then
|
||||
JAVACMD="`/usr/libexec/java_home -F -v ${JVMVersion} 2> /dev/null`/bin/java"
|
||||
JAVACMD_version=$(comparableJavaVersionNumber $(extractJavaVersionString "${JAVACMD}"))
|
||||
fi
|
||||
|
||||
# then additionally check the Oracle JRE plugin whether it's a higher/newer compatible version
|
||||
if [ -x "${oracle_jre_plugin}" ] && JavaVersionSatisfiesRequirement ${oracle_jre_version} ${JVMVersion} ; then
|
||||
this_java_ver=$(comparableJavaVersionNumber $(extractJavaVersionString "${oracle_jre_plugin}"))
|
||||
# use this compatible version only if the above returned empty or if the version number is higher
|
||||
if [ -z ${JAVACMD} ] || [ ${this_java_ver} -ge ${JAVACMD_version} ] ; then
|
||||
JAVACMD="${oracle_jre_plugin}"
|
||||
JAVACMD_version=${this_java_ver}
|
||||
fi
|
||||
fi
|
||||
|
||||
# then additionally check the Apple JRE plugin whether it's a higher/newer compatible version
|
||||
if [ -x "${apple_jre_plugin}" ] && JavaVersionSatisfiesRequirement ${apple_jre_version} ${JVMVersion} ; then
|
||||
this_java_ver=$(comparableJavaVersionNumber $(extractJavaVersionString "${apple_jre_plugin}"))
|
||||
# use this compatible version only if the above returned empty or if the version number is higher
|
||||
if [ -z ${JAVACMD} ] || [ ${this_java_ver} -ge ${JAVACMD_version} ] ; then
|
||||
JAVACMD="${apple_jre_plugin}"
|
||||
JAVACMD_version=${this_java_ver}
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
# display human readable java version (#28)
|
||||
java_version_hr=`echo ${JVMVersion} | sed -E 's/[0-9]\.([0-9+*]+)/ \1/g' | sed "s/+/ ${MSG_JAVA_VERSION_OR_LATER}/" | sed "s/*/ ${MSG_JAVA_VERSION_LATEST}/"`
|
||||
# display error message with applescript
|
||||
osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA}${java_version_hr}.\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\" buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\"} default button \"${MSG_VISIT_JAVA_DOT_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 \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
|
||||
# exit with error
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# otherwise check "/usr/libexec/java_home" and Oracle and Apple JRE paths and use highest version available
|
||||
else
|
||||
|
||||
# first check "/usr/libexec/java_home" symlinks
|
||||
if [ -x /usr/libexec/java_home ] && /usr/libexec/java_home -F > /dev/null 2>&1 ; then
|
||||
JAVACMD="`/usr/libexec/java_home 2> /dev/null`/bin/java"
|
||||
JAVACMD_version=$(comparableJavaVersionNumber $(extractJavaVersionString "${JAVACMD}"))
|
||||
fi
|
||||
|
||||
# then additionally check the Oracle JRE plugin whether it's a higher/newer compatible version
|
||||
if [ -x "${oracle_jre_plugin}" ] ; then
|
||||
this_java_ver=$(comparableJavaVersionNumber $(extractJavaVersionString "${oracle_jre_plugin}"))
|
||||
# use this compatible version only if the above returned empty or if the version number is higher
|
||||
if [ -z ${JAVACMD} ] || [ ${this_java_ver} -ge ${JAVACMD_version} ] ; then
|
||||
JAVACMD="${oracle_jre_plugin}"
|
||||
JAVACMD_version=${this_java_ver}
|
||||
fi
|
||||
fi
|
||||
|
||||
# then additionally check the Apple JRE plugin whether it's a higher/newer compatible version
|
||||
if [ -x "${apple_jre_plugin}" ] ; then
|
||||
this_java_ver=$(comparableJavaVersionNumber $(extractJavaVersionString "${apple_jre_plugin}"))
|
||||
# use this compatible version only if the above returned empty or if the version number is higher
|
||||
if [ -z ${JAVACMD} ] || [ ${this_java_ver} -ge ${JAVACMD_version} ] ; then
|
||||
JAVACMD="${apple_jre_plugin}"
|
||||
JAVACMD_version=${this_java_ver}
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# fallback fallback: /usr/bin/java
|
||||
# but this would prompt to install deprecated Apple Java 6
|
||||
|
||||
|
||||
|
||||
#
|
||||
# execute JAVA commandline and do some pre-checks
|
||||
####################################################
|
||||
|
||||
# display error message if MainClassName is empty
|
||||
if [ -z ${JVMMainClass} ]; then
|
||||
# display error message with applescript
|
||||
osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_MISSING_MAINCLASS}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
|
||||
# exit with error
|
||||
exit 2
|
||||
|
||||
|
||||
# check whether $JAVACMD is a file and executable
|
||||
elif [ -f "$JAVACMD" ] && [ -x "$JAVACMD" ] ; then
|
||||
|
||||
# enable drag&drop to the dock icon
|
||||
export CFProcessPath="$0"
|
||||
|
||||
# remove Apples ProcessSerialNumber from passthru arguments (#39)
|
||||
if [[ $@ == -psn* ]] ; then
|
||||
ArgsPassthru=""
|
||||
else
|
||||
ArgsPassthru=$@
|
||||
fi
|
||||
|
||||
# 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}" \
|
||||
-splash:"${ResourcesFolder}/${JVMSplashFile}" \
|
||||
-Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \
|
||||
-Xdock:name="${CFBundleName}" \
|
||||
${JVMOptions:+$JVMOptions }\
|
||||
${JVMDefaultOptions:+$JVMDefaultOptions }\
|
||||
${JVMMainClass}\
|
||||
${JVMArguments:+ $JVMArguments}\
|
||||
${ArgsPassthru:+ $ArgsPassthru}
|
||||
|
||||
|
||||
else
|
||||
|
||||
# display error message with applescript
|
||||
osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_INSTALL_JAVA}\" with title \"${CFBundleName}\" buttons {\"${MSG_LATER}\", \"${MSG_VISIT_JAVA_DOT_COM}\"} default button \"${MSG_VISIT_JAVA_DOT_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 \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
|
||||
|
||||
# exit with error
|
||||
exit 1
|
||||
fi
|
Loading…
Reference in New Issue
Block a user