Skip to content

Commit 3576f80

Browse files
authored
Merge branch 'tofi86:master' into master
2 parents 43c25c8 + 8bcbdba commit 3576f80

File tree

5 files changed

+144
-53
lines changed

5 files changed

+144
-53
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ko_fi: tofi86

.github/issue_template.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
11
I'm submitting a…
22

3-
- [x] bug report
3+
<!--
4+
Place an 'x' inside the square brackets like this [x]
5+
of the list item that matches your request.
6+
Delete the other unused list items.
7+
-->
8+
9+
- [ ] bug report
410
- [ ] feature request
511
- [ ] other
612

13+
<!--
14+
If you checked 'other':
15+
Do you have a general question about how a feature works
16+
or would like to share an idea or a usecase for this project?
17+
THEN PLEASE use the >>DISCUSSION<< page of this project over at
18+
https://github.com/tofi86/universalJavaApplicationStub/discussions
19+
-->
20+
21+
722
**Short description of the issue/suggestion:**
823

924

@@ -14,6 +29,7 @@ I'm submitting a…
1429
2. [Second Step]
1530
3. [Other Steps...]
1631

32+
1733
**What is the expected behavior?**
1834

1935

@@ -33,7 +49,12 @@ I'm submitting a…
3349
**Please tell us about your environment:**
3450

3551
- universalJavaApplicationStub version:
36-
- Mac OS version:
52+
- macOS version:
3753
- Java version(s):
3854

39-
**Other information** (e.g. related issues, suggestions how to fix, links for us to have context)
55+
56+
**Other information:**
57+
58+
<!-- e.g. related issues, suggestions how to fix, links for us to have context, etc. -->
59+
60+

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88

9+
## [3.2.0] - 2021-02-21
10+
### Added
11+
- Also expand variables `$APP_PACKAGE`, `$JAVAROOT` and `$USER_HOME` in Oracle style PList files
12+
- Also expand variable `$APP_ROOT` in Apple style PList files
13+
- Oracle JVMDefaultOptions key: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#99)
14+
15+
### Changed
16+
- 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)
17+
- Improved logging for JAVA_HOME detection (#100)
18+
19+
### Fixed
20+
- Fixed a crash when `/usr/libexec/java_home` returns no JVMs (#93)
21+
22+
923
## [3.1.0] - 2021-01-07
1024
### Added
1125
- Support for macOS 11.0 "Big Sur" (#91)

README.md

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
universalJavaApplicationStub
22
============================
33

4-
![Tests and Shellcheck](https://github.com/tofi86/universalJavaApplicationStub/workflows/Tests%20and%20Shellcheck/badge.svg) [![Current release](https://img.shields.io/github/release/tofi86/universalJavaApplicationStub.svg)](https://github.com/tofi86/universalJavaApplicationStub/releases) [![Join the chat at https://gitter.im/tofi86/universalJavaApplicationStub](https://badges.gitter.im/tofi86/universalJavaApplicationStub.svg)](https://gitter.im/tofi86/universalJavaApplicationStub?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4+
![Tests and Shellcheck](https://github.com/tofi86/universalJavaApplicationStub/workflows/Tests%20and%20Shellcheck/badge.svg) [![Current release](https://img.shields.io/github/release/tofi86/universalJavaApplicationStub.svg)](https://github.com/tofi86/universalJavaApplicationStub/releases) [![Donate to this project using Buy Me A Coffee](https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg)](https://ko-fi.com/tofi86)
55

6-
A BASH based *JavaApplicationStub* for Java Apps on Mac OS X that works with both Apple's and Oracle's plist format. It is released under the [MIT License](https://github.com/tofi86/universalJavaApplicationStub/blob/master/LICENSE).
6+
A BASH based _launcher stub_ for Java based macOS Apps that works with both Apple's and Oracle's plist format. It is released under the [MIT License](https://github.com/tofi86/universalJavaApplicationStub/blob/master/LICENSE).
77

8-
See the [CHANGELOG](https://github.com/tofi86/universalJavaApplicationStub/blob/master/CHANGELOG.md) for a Release History and feature details.
8+
📃 🔄 See the [CHANGELOG](https://github.com/tofi86/universalJavaApplicationStub/blob/master/CHANGELOG.md) for a Release History and feature details.
9+
10+
🐛 🔥 Report _Issues_ at the [GitHub Issues Page](https://github.com/tofi86/universalJavaApplicationStub/issues).
11+
12+
🤔 ❓ If you have a _general question_ about how a feature works or would like to _share an idea_ or a _usecase for this project_, then please use the [GitHub Discussions Page](https://github.com/tofi86/universalJavaApplicationStub/discussions).
13+
14+
❤️ ☕ If you want to support this independent project, you can buy me a coffee: [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/tofi86)
915

1016

1117
Why
@@ -151,20 +157,21 @@ You should get a fully functional Mac Application Bundle working with both Java
151157
Supported PList keys
152158
--------------------
153159

154-
| Function | Apple PList key | Oracle PList key |
155-
|---------------------------------|------------------------|-----------------------|
156-
| **App Name** (Dock Name) | `:CFBundleName` | `:CFBundleName` |
157-
| **App Icon** (Dock Icon) | `:CFBundleIconFile` | `:CFBundleIconFile` |
158-
| **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/` |
159-
| **Java Min/Max[*](https://github.com/tofi86/universalJavaApplicationStub/issues/51) Version Requirement** | `:Java(X):JVMVersion` | `:JVMVersion` |
160-
| **Java ClassPath** (`-cp …`) | `:Java(X):ClassPath` | `:JVMClassPath` |
161-
| **Java Main Class** | `:Java(X):MainClass` | `:JVMMainClassName` |
162-
| **Splash Image** (`-splash:…`) | `:Java(X):SplashFile` | `:JVMSplashFile` |
163-
| **Java VM Options** (`-X…`) | `:Java(X):VMOptions` | `:JVMDefaultOptions` |
164-
| **`-XstartOnFirstThread`** [*](https://stackoverflow.com/questions/28149634/what-does-the-xstartonfirstthread-vm-argument-do-mean) | `:Java(X):StartOnMainThread` | *not supported* |
165-
| **Java Properties** (`-D…`) | `:Java(X):Properties` | `:JVMOptions` |
166-
| **Main Class Arguments** | `:Java(X):Arguments` | `:JVMArguments` |
167-
160+
| Function | Apple PList key | Oracle PList key |
161+
|--------------------------------------------|------------------------|-----------------------|
162+
| **App Name** (Dock Name) | `:CFBundleName` | `:CFBundleName` |
163+
| **App Icon** (Dock Icon) | `:CFBundleIconFile` | `:CFBundleIconFile` |
164+
| **Working Directory** <sup>🌟</sup> | `:Java(X):WorkingDirectory`<br/>fallback to `name.app/ | *not supported*<br/>default: `name.app/Contents/Java/` |
165+
| **Java Min/Max<sup>[](https://github.com/tofi86/universalJavaApplicationStub/issues/51)</sup> Version Requirement** | `:Java(X):JVMVersion` | `:JVMVersion` |
166+
| **Java ClassPath** (`-cp …`) <sup>🌟</sup> | `:Java(X):ClassPath` | `:JVMClassPath` |
167+
| **Java Main Class** | `:Java(X):MainClass` | `:JVMMainClassName` |
168+
| **Splash Image** (`-splash:…`) | `:Java(X):SplashFile` | `:JVMSplashFile` |
169+
| **Java VM Options** (`-X…`) <sup>🌟</sup> | `:Java(X):VMOptions` | `:JVMDefaultOptions` |
170+
| **`-XstartOnFirstThread`** <sup>[](https://stackoverflow.com/questions/28149634/what-does-the-xstartonfirstthread-vm-argument-do-mean)</sup> | `:Java(X):StartOnMainThread` | *not supported* |
171+
| **Java Properties** (`-D…`) <sup>🌟</sup> | `:Java(X):Properties` | `:JVMOptions` |
172+
| **Main Class Arguments** <sup>🌟</sup> | `:Java(X):Arguments` | `:JVMArguments` |
173+
174+
<sup>🌟</sup> Variable placeholders `$APP_PACKAGE`, `$APP_ROOT`, `$JAVAROOT`, `$USER_HOME` get expanded in these contexts.
168175

169176
### Specify min/max Java requirement
170177

src/universalJavaApplicationStub

Lines changed: 81 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
# #
1212
# @author Tobias Fischer #
1313
# @url https://github.com/tofi86/universalJavaApplicationStub #
14-
# @date 2021-01-07 #
15-
# @version 3.1.0 #
14+
# @date 2021-02-21 #
15+
# @version 3.2.0 #
1616
# #
1717
##################################################################################
1818
# #
@@ -166,6 +166,8 @@ if [ $exitcode -eq 0 ]; then
166166
JavaFolder="${AppleJavaFolder}"
167167
ResourcesFolder="${AppleResourcesFolder}"
168168

169+
# set expandable variables
170+
APP_ROOT="${AppPackageFolder}"
169171
APP_PACKAGE="${AppPackageFolder}"
170172
JAVAROOT="${AppleJavaFolder}"
171173
USER_HOME="$HOME"
@@ -180,7 +182,7 @@ if [ $exitcode -eq 0 ]; then
180182
# AppPackageRoot is the standard WorkingDirectory when the script is started
181183
WorkingDirectory="${AppPackageRoot}"
182184
fi
183-
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
185+
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
184186
WorkingDirectory=$(eval echo "${WorkingDirectory}")
185187

186188

@@ -203,7 +205,7 @@ if [ $exitcode -eq 0 ]; then
203205
else
204206
JVMClassPath=${JVMClassPath_RAW}
205207
fi
206-
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
208+
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
207209
JVMClassPath=$(eval echo "${JVMClassPath}")
208210

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

219221
# read StartOnMainThread and add as -XstartOnFirstThread
@@ -249,7 +251,11 @@ else
249251
ResourcesFolder="${OracleResourcesFolder}"
250252
WorkingDirectory="${OracleJavaFolder}"
251253

254+
# set expandable variables
252255
APP_ROOT="${AppPackageFolder}"
256+
APP_PACKAGE="${AppPackageFolder}"
257+
JAVAROOT="${OracleJavaFolder}"
258+
USER_HOME="$HOME"
253259

254260
# read the MainClass name
255261
JVMMainClass="$(plist_get ':JVMMainClassName')"
@@ -267,12 +273,12 @@ else
267273
JVMClassPath_RAW=$(plist_get ':JVMClassPath')
268274
if [[ $JVMClassPath_RAW == *Array* ]] ; then
269275
JVMClassPath=.$(plist_get ':JVMClassPath' | grep " " | sed 's/^ */:/g' | tr -d '\n' | xargs)
270-
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
276+
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
271277
JVMClassPath=$(eval echo "${JVMClassPath}")
272278

273279
elif [[ ! -z ${JVMClassPath_RAW} ]] ; then
274280
JVMClassPath=${JVMClassPath_RAW}
275-
# expand variables $APP_PACKAGE, $JAVAROOT, $USER_HOME
281+
# expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
276282
JVMClassPath=$(eval echo "${JVMClassPath}")
277283

278284
else
@@ -281,8 +287,11 @@ else
281287
# Do NOT expand the default 'AppName.app/Contents/Java/*' classpath (#42)
282288
fi
283289

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

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

327-
# MainArgs: replace occurences of $APP_ROOT with its content
336+
# MainArgs: expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME
328337
MainArgsArr=()
329338
for i in "${MainArgs[@]}"
330339
do
331340
MainArgsArr+=("$(eval echo "$i")")
332341
done
333342

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

345-
LANG=$(defaults read -g AppleLocale)
346-
stub_logger "[Language] $LANG"
354+
# supported languages / available translations
355+
stubLanguages="^(fr|de|zh|es|en)-"
356+
357+
# read user preferred languages as defined in macOS System Preferences (#101)
358+
stub_logger '[LanguageSearch] Checking preferred languages in macOS System Preferences...'
359+
appleLanguages=($(defaults read -g AppleLanguages | grep '\s"' | tr -d ',' | xargs))
360+
stub_logger "[LanguageSearch] ... found [${appleLanguages[*]}]"
361+
362+
language=""
363+
for i in "${appleLanguages[@]}"
364+
do
365+
langValue="${i%-*}"
366+
if [[ "$i" =~ $stubLanguages ]]; then
367+
stub_logger "[LanguageSearch] ... selected '$i' ('$langValue') as the default language for the launcher stub"
368+
language=${langValue}
369+
break
370+
fi
371+
done
372+
if [ -z "${language}" ]; then
373+
language="en"
374+
stub_logger "[LanguageSearch] ... selected fallback 'en' as the default language for the launcher stub"
375+
fi
376+
stub_logger "[Language] $language"
377+
347378

348-
# French localization
349-
if [[ $LANG == fr* ]] ; then
379+
case "${language}" in
380+
# French
381+
fr)
350382
MSG_ERROR_LAUNCHING="ERREUR au lancement de '${CFBundleName}'."
351383
MSG_MISSING_MAINCLASS="'MainClass' n'est pas spécifié.\nL'application Java ne peut pas être lancée."
352384
MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version de Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
@@ -359,9 +391,10 @@ if [[ $LANG == fr* ]] ; then
359391
MSG_LATER="Plus tard"
360392
MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
361393
MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
394+
;;
362395

363-
# German localization
364-
elif [[ $LANG == de* ]] ; then
396+
# German
397+
de)
365398
MSG_ERROR_LAUNCHING="FEHLER beim Starten von '${CFBundleName}'."
366399
MSG_MISSING_MAINCLASS="Die 'MainClass' ist nicht spezifiziert!\nDie Java-Anwendung kann nicht gestartet werden!"
367400
MSG_JVMVERSION_REQ_INVALID="Die Syntax der angeforderten Java-Version ist ungültig: %s\nBitte kontaktieren Sie den Entwickler der App."
@@ -374,9 +407,10 @@ elif [[ $LANG == de* ]] ; then
374407
MSG_LATER="Später"
375408
MSG_VISIT_JAVA_DOT_COM="Java von Oracle"
376409
MSG_VISIT_ADOPTOPENJDK="Java von AdoptOpenJDK"
410+
;;
377411

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

393-
# Spanish localization
394-
elif [[ $LANG == es* ]] ; then
428+
# Spanish
429+
es)
395430
MSG_ERROR_LAUNCHING="ERROR iniciando '${CFBundleName}'."
396431
MSG_MISSING_MAINCLASS="¡'MainClass' no especificada!\n¡La aplicación Java no puede iniciarse!"
397432
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."
@@ -404,9 +439,10 @@ elif [[ $LANG == es* ]] ; then
404439
MSG_LATER="Más tarde"
405440
MSG_VISIT_JAVA_DOT_COM="Java de Oracle"
406441
MSG_VISIT_ADOPTOPENJDK="Java de AdoptOpenJDK"
442+
;;
407443

408-
# English default localization
409-
else
444+
# English default
445+
en|*)
410446
MSG_ERROR_LAUNCHING="ERROR launching '${CFBundleName}'."
411447
MSG_MISSING_MAINCLASS="'MainClass' isn't specified!\nJava application cannot be started!"
412448
MSG_JVMVERSION_REQ_INVALID="The syntax of the required Java version is invalid: %s\nPlease contact the App developer."
@@ -419,7 +455,8 @@ else
419455
MSG_LATER="Later"
420456
MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
421457
MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
422-
fi
458+
;;
459+
esac
423460

424461

425462

@@ -535,19 +572,27 @@ if [ -n "$JAVA_HOME" ] ; then
535572
if [[ $JAVA_HOME == /* ]] ; then
536573
# if "$JAVA_HOME" starts with a Slash it's an absolute path
537574
JAVACMD="$JAVA_HOME/bin/java"
575+
stub_logger "[JavaSearch] ... parsing JAVA_HOME as absolute path to the executable '$JAVACMD'"
538576
else
539577
# otherwise it's a relative path to "$AppPackageFolder"
540578
JAVACMD="$AppPackageFolder/$JAVA_HOME/bin/java"
579+
stub_logger "[JavaSearch] ... parsing JAVA_HOME as relative path inside the App bundle to the executable '$JAVACMD'"
541580
fi
542581
JAVACMD_version=$(get_comparable_java_version $(get_java_version_from_cmd "${JAVACMD}"))
543582
else
544-
stub_logger "[JavaSearch] ... didn't found JAVA_HOME"
583+
stub_logger "[JavaSearch] ... haven't found JAVA_HOME"
545584
fi
546585

547586

548587
# check for any other or a specific Java version
549588
# also if $JAVA_HOME exists but isn't executable
550589
if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
590+
591+
# add a warning in the syslog if JAVA_HOME is not executable or not found (#100)
592+
if [ -n "$JAVA_HOME" ] ; then
593+
stub_logger "[JavaSearch] ... but no 'java' executable was found at the JAVA_HOME location!"
594+
fi
595+
551596
stub_logger "[JavaSearch] Searching for JavaVirtualMachines on the system ..."
552597
# reset variables
553598
JAVACMD=""
@@ -584,15 +629,18 @@ if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
584629
javaCounter=$(/usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< $javaXml | grep "Dict" | wc -l | tr -d ' ')
585630

586631
# iterate over all Dict entries
587-
for idx in $(seq 0 $((javaCounter - 1)))
588-
do
589-
version=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMVersion" /dev/stdin <<< $javaXml)
590-
path=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMHomePath" /dev/stdin <<< $javaXml)
591-
path+="/bin/java"
592-
allJVMs+=("$version:$path")
593-
done
594-
# unset for loop variables
595-
unset version path
632+
# but only if there are any JVMs at all (#93)
633+
if [ "$javaCounter" -gt "0" ] ; then
634+
for idx in $(seq 0 $((javaCounter - 1)))
635+
do
636+
version=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMVersion" /dev/stdin <<< $javaXml)
637+
path=$(/usr/libexec/PlistBuddy -c "print :$idx:JVMHomePath" /dev/stdin <<< $javaXml)
638+
path+="/bin/java"
639+
allJVMs+=("$version:$path")
640+
done
641+
# unset for loop variables
642+
unset version path
643+
fi
596644

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

0 commit comments

Comments
 (0)