Skip to content
This repository has been archived by the owner on Feb 4, 2023. It is now read-only.

Commit

Permalink
Release version 3.2.0 (PR #107)
Browse files Browse the repository at this point in the history
  • Loading branch information
tofi86 authored Feb 21, 2021
2 parents 6c96e68 + 2dbbf92 commit e4f96e7
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 47 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [3.2.0] - 2021-02-21
### Added
- Also expand variables `$APP_PACKAGE`, `$JAVAROOT` and `$USER_HOME` in Oracle style PList files
- Also expand variable `$APP_ROOT` in Apple style PList files
- Oracle JVMDefaultOptions key: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#99)

### Changed
- Improved language detection by reading the user preferred languages from the macOS System Preferences instead of using the system locale (#101, thanks to @Flexperte for his valuable feedback)
- Improved logging for JAVA_HOME detection (#100)

### Fixed
- Fixed a crash when `/usr/libexec/java_home` returns no JVMs (#93)


## [3.1.0] - 2021-01-07
### Added
- Support for macOS 11.0 "Big Sur" (#91)
Expand Down
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,20 +151,21 @@ You should get a fully functional Mac Application Bundle working with both Java
Supported PList keys
--------------------

| Function | Apple PList key | Oracle PList key |
|---------------------------------|------------------------|-----------------------|
| **App Name** (Dock Name) | `:CFBundleName` | `:CFBundleName` |
| **App Icon** (Dock Icon) | `:CFBundleIconFile` | `:CFBundleIconFile` |
| **Working Directory** | `:Java(X):WorkingDirectory`<br/>fallback to `name.app/`<br/>support for variables `$APP_PACKAGE`, `$JAVAROOT`, `$USER_HOME` | *not supported*<br/>default: `name.app/Contents/Java/` |
| **Java Min/Max[*](https://github.com/tofi86/universalJavaApplicationStub/issues/51) Version Requirement** | `:Java(X):JVMVersion` | `:JVMVersion` |
| **Java ClassPath** (`-cp …`) | `:Java(X):ClassPath` | `:JVMClassPath` |
| **Java Main Class** | `:Java(X):MainClass` | `:JVMMainClassName` |
| **Splash Image** (`-splash:…`) | `:Java(X):SplashFile` | `:JVMSplashFile` |
| **Java VM Options** (`-X…`) | `:Java(X):VMOptions` | `:JVMDefaultOptions` |
| **`-XstartOnFirstThread`** [*](https://stackoverflow.com/questions/28149634/what-does-the-xstartonfirstthread-vm-argument-do-mean) | `:Java(X):StartOnMainThread` | *not supported* |
| **Java Properties** (`-D…`) | `:Java(X):Properties` | `:JVMOptions` |
| **Main Class Arguments** | `:Java(X):Arguments` | `:JVMArguments` |

| Function | Apple PList key | Oracle PList key |
|--------------------------------------------|------------------------|-----------------------|
| **App Name** (Dock Name) | `:CFBundleName` | `:CFBundleName` |
| **App Icon** (Dock Icon) | `:CFBundleIconFile` | `:CFBundleIconFile` |
| **Working Directory** <sup>🌟</sup> | `:Java(X):WorkingDirectory`<br/>fallback to `name.app/ | *not supported*<br/>default: `name.app/Contents/Java/` |
| **Java Min/Max<sup>[](https://github.com/tofi86/universalJavaApplicationStub/issues/51)</sup> Version Requirement** | `:Java(X):JVMVersion` | `:JVMVersion` |
| **Java ClassPath** (`-cp …`) <sup>🌟</sup> | `:Java(X):ClassPath` | `:JVMClassPath` |
| **Java Main Class** | `:Java(X):MainClass` | `:JVMMainClassName` |
| **Splash Image** (`-splash:…`) | `:Java(X):SplashFile` | `:JVMSplashFile` |
| **Java VM Options** (`-X…`) <sup>🌟</sup> | `:Java(X):VMOptions` | `:JVMDefaultOptions` |
| **`-XstartOnFirstThread`** <sup>[](https://stackoverflow.com/questions/28149634/what-does-the-xstartonfirstthread-vm-argument-do-mean)</sup> | `:Java(X):StartOnMainThread` | *not supported* |
| **Java Properties** (`-D…`) <sup>🌟</sup> | `:Java(X):Properties` | `:JVMOptions` |
| **Main Class Arguments** <sup>🌟</sup> | `:Java(X):Arguments` | `:JVMArguments` |

<sup>🌟</sup> Variable placeholders `$APP_PACKAGE`, `$APP_ROOT`, `$JAVAROOT`, `$USER_HOME` get expanded in these contexts.

### Specify min/max Java requirement

Expand Down
114 changes: 81 additions & 33 deletions src/universalJavaApplicationStub
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
# #
# @author Tobias Fischer #
# @url https://github.com/tofi86/universalJavaApplicationStub #
# @date 2021-01-07 #
# @version 3.1.0 #
# @date 2021-02-21 #
# @version 3.2.0 #
# #
##################################################################################
# #
Expand Down Expand Up @@ -166,6 +166,8 @@ if [ $exitcode -eq 0 ]; then
JavaFolder="${AppleJavaFolder}"
ResourcesFolder="${AppleResourcesFolder}"

# set expandable variables
APP_ROOT="${AppPackageFolder}"
APP_PACKAGE="${AppPackageFolder}"
JAVAROOT="${AppleJavaFolder}"
USER_HOME="$HOME"
Expand All @@ -180,7 +182,7 @@ if [ $exitcode -eq 0 ]; then
# AppPackageRoot is the standard WorkingDirectory when the script is started
WorkingDirectory="${AppPackageRoot}"
fi
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
WorkingDirectory=$(eval echo "${WorkingDirectory}")


Expand All @@ -203,7 +205,7 @@ if [ $exitcode -eq 0 ]; then
else
JVMClassPath=${JVMClassPath_RAW}
fi
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
JVMClassPath=$(eval echo "${JVMClassPath}")

# read the JVM Options in either Array or String style
Expand All @@ -213,7 +215,7 @@ if [ $exitcode -eq 0 ]; then
else
JVMDefaultOptions=${JVMDefaultOptions_RAW}
fi
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME (#84)
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#84)
JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")

# read StartOnMainThread and add as -XstartOnFirstThread
Expand Down Expand Up @@ -247,7 +249,11 @@ else
ResourcesFolder="${OracleResourcesFolder}"
WorkingDirectory="${OracleJavaFolder}"

# set expandable variables
APP_ROOT="${AppPackageFolder}"
APP_PACKAGE="${AppPackageFolder}"
JAVAROOT="${OracleJavaFolder}"
USER_HOME="$HOME"

# read the MainClass name
JVMMainClass="$(plist_get ':JVMMainClassName')"
Expand All @@ -265,12 +271,12 @@ else
JVMClassPath_RAW=$(plist_get ':JVMClassPath')
if [[ $JVMClassPath_RAW == *Array* ]] ; then
JVMClassPath=.$(plist_get ':JVMClassPath' | grep " " | sed 's/^ */:/g' | tr -d '\n' | xargs)
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
JVMClassPath=$(eval echo "${JVMClassPath}")

elif [[ ! -z ${JVMClassPath_RAW} ]] ; then
JVMClassPath=${JVMClassPath_RAW}
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
JVMClassPath=$(eval echo "${JVMClassPath}")

else
Expand All @@ -279,8 +285,11 @@ else
# Do NOT expand the default 'AppName.app/Contents/Java/*' classpath (#42)
fi

# read the JVM Default Options
# read the JVM Default Options by parsing the :JVMDefaultOptions <dict>
# and pulling all <string> values starting with a dash (-)
JVMDefaultOptions=$(plist_get ':JVMDefaultOptions' | grep -o " \-.*" | tr -d '\n' | xargs)
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#99)
JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")

# read the Main Arguments from JVMArguments key as an array and retain spaces (see #46 for naming details)
IFS=$'\t\n'
Expand Down Expand Up @@ -316,14 +325,14 @@ fi
stub_logger "[JavaRequirement] JVM minimum version: ${JVMVersion}"
stub_logger "[JavaRequirement] JVM maximum version: ${JVMMaxVersion}"

# MainArgs: replace occurences of $APP_ROOT with its content
# MainArgs: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
MainArgsArr=()
for i in "${MainArgs[@]}"
do
MainArgsArr+=("$(eval echo "$i")")
done

# JVMOptions: replace occurences of $APP_ROOT with its content
# JVMOptions: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
JVMOptionsArr=()
for i in "${JVMOptions[@]}"
do
Expand All @@ -334,11 +343,34 @@ done
# internationalized messages
############################################

LANG=$(defaults read -g AppleLocale)
stub_logger "[Language] $LANG"
# supported languages / available translations
stubLanguages="^(fr|de|zh|es|en)-"

# read user preferred languages as defined in macOS System Preferences (#101)
stub_logger '[LanguageSearch] Checking preferred languages in macOS System Preferences...'
appleLanguages=($(defaults read -g AppleLanguages | grep '\s"' | tr -d ',' | xargs))
stub_logger "[LanguageSearch] ... found [${appleLanguages[*]}]"

language=""
for i in "${appleLanguages[@]}"
do
langValue="${i%-*}"
if [[ "$i" =~ $stubLanguages ]]; then
stub_logger "[LanguageSearch] ... selected '$i' ('$langValue') as the default language for the launcher stub"
language=${langValue}
break
fi
done
if [ -z "${language}" ]; then
language="en"
stub_logger "[LanguageSearch] ... selected fallback 'en' as the default language for the launcher stub"
fi
stub_logger "[Language] $language"


# French localization
if [[ $LANG == fr* ]] ; then
case "${language}" in
# French
fr)
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_JVMVERSION_REQ_INVALID="La syntaxe de la version de Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
Expand All @@ -351,9 +383,10 @@ if [[ $LANG == fr* ]] ; then
MSG_LATER="Plus tard"
MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
;;

# German localization
elif [[ $LANG == de* ]] ; then
# German
de)
MSG_ERROR_LAUNCHING="FEHLER beim Starten von '${CFBundleName}'."
MSG_MISSING_MAINCLASS="Die 'MainClass' ist nicht spezifiziert!\nDie Java-Anwendung kann nicht gestartet werden!"
MSG_JVMVERSION_REQ_INVALID="Die Syntax der angeforderten Java-Version ist ungültig: %s\nBitte kontaktieren Sie den Entwickler der App."
Expand All @@ -366,9 +399,10 @@ elif [[ $LANG == de* ]] ; then
MSG_LATER="Später"
MSG_VISIT_JAVA_DOT_COM="Java von Oracle"
MSG_VISIT_ADOPTOPENJDK="Java von AdoptOpenJDK"
;;

# Simplifyed Chinese localization
elif [[ $LANG == zh* ]] ; then
# Simplified Chinese
zh)
MSG_ERROR_LAUNCHING="无法启动 '${CFBundleName}'."
MSG_MISSING_MAINCLASS="没有指定 'MainClass'!\nJava程序无法启动!"
MSG_JVMVERSION_REQ_INVALID="Java版本参数语法错误: %s\n请联系该应用的开发者。"
Expand All @@ -381,9 +415,10 @@ elif [[ $LANG == zh* ]] ; then
MSG_LATER="稍后"
MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
;;

# Spanish localization
elif [[ $LANG == es* ]] ; then
# Spanish
es)
MSG_ERROR_LAUNCHING="ERROR iniciando '${CFBundleName}'."
MSG_MISSING_MAINCLASS="¡'MainClass' no especificada!\n¡La aplicación Java no puede iniciarse!"
MSG_JVMVERSION_REQ_INVALID="La sintaxis de la versión Java requerida no es válida: %s\nPor favor, contacte con el desarrollador de la aplicación."
Expand All @@ -396,9 +431,10 @@ elif [[ $LANG == es* ]] ; then
MSG_LATER="Más tarde"
MSG_VISIT_JAVA_DOT_COM="Java de Oracle"
MSG_VISIT_ADOPTOPENJDK="Java de AdoptOpenJDK"
;;

# English default localization
else
# English default
en|*)
MSG_ERROR_LAUNCHING="ERROR launching '${CFBundleName}'."
MSG_MISSING_MAINCLASS="'MainClass' isn't specified!\nJava application cannot be started!"
MSG_JVMVERSION_REQ_INVALID="The syntax of the required Java version is invalid: %s\nPlease contact the App developer."
Expand All @@ -411,7 +447,8 @@ else
MSG_LATER="Later"
MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
fi
;;
esac



Expand Down Expand Up @@ -527,19 +564,27 @@ if [ -n "$JAVA_HOME" ] ; then
if [[ $JAVA_HOME == /* ]] ; then
# if "$JAVA_HOME" starts with a Slash it's an absolute path
JAVACMD="$JAVA_HOME/bin/java"
stub_logger "[JavaSearch] ... parsing JAVA_HOME as absolute path to the executable '$JAVACMD'"
else
# otherwise it's a relative path to "$AppPackageFolder"
JAVACMD="$AppPackageFolder/$JAVA_HOME/bin/java"
stub_logger "[JavaSearch] ... parsing JAVA_HOME as relative path inside the App bundle to the executable '$JAVACMD'"
fi
JAVACMD_version=$(get_comparable_java_version $(get_java_version_from_cmd "${JAVACMD}"))
else
stub_logger "[JavaSearch] ... didn't found JAVA_HOME"
stub_logger "[JavaSearch] ... haven't found JAVA_HOME"
fi


# check for any other or a specific Java version
# also if $JAVA_HOME exists but isn't executable
if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then

# add a warning in the syslog if JAVA_HOME is not executable or not found (#100)
if [ -n "$JAVA_HOME" ] ; then
stub_logger "[JavaSearch] ... but no 'java' executable was found at the JAVA_HOME location!"
fi

stub_logger "[JavaSearch] Searching for JavaVirtualMachines on the system ..."
# reset variables
JAVACMD=""
Expand Down Expand Up @@ -576,15 +621,18 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
javaCounter=$(/usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< $javaXml | grep "Dict" | wc -l | tr -d ' ')

# iterate over all Dict entries
for idx in $(seq 0 $((javaCounter - 1)))
do
version=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMVersion" /dev/stdin <<< $javaXml)
path=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMHomePath" /dev/stdin <<< $javaXml)
path+="/bin/java"
allJVMs+=("$version:$path")
done
# unset for loop variables
unset version path
# but only if there are any JVMs at all (#93)
if [ "$javaCounter" -gt "0" ] ; then
for idx in $(seq 0 $((javaCounter - 1)))
do
version=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMVersion" /dev/stdin <<< $javaXml)
path=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMHomePath" /dev/stdin <<< $javaXml)
path+="/bin/java"
allJVMs+=("$version:$path")
done
# unset for loop variables
unset version path
fi

# add SDKMAN! java versions (#95)
if [ -d ~/.sdkman/candidates/java/ ] ; then
Expand Down

0 comments on commit e4f96e7

Please sign in to comment.