src/easymega-v1.0/easymega-v1.0-$(VERSION).ihx \
src/easymega-v2.0/easymega-v2.0-$(VERSION).ihx \
src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx \
+ src/easymotor-v2/easymotor-v2-$(VERSION).ihx \
src/easytimer-v1/easytimer-v1-$(VERSION).ihx \
src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx \
src/telebt-v4.0/telebt-v4.0-$(VERSION).ihx \
src/easymega-v2.0/{*.elf,*.ihx,*.map} \
src/easymini-v1.0/{*.elf,*.ihx,*.map} \
src/easymini-v2.0/{*.elf,*.ihx,*.map} \
+ src/easymotor-v2/{*.elf,*.ihx,*.map} \
src/easytimer-v1/{*.elf,*.ihx,*.map} \
src/telebt-v3.0/{*.elf,*.ihx,*.map} \
src/telebt-v4.0/{*.elf,*.ihx,*.map} \
src/easymega-v2.0/flash-loader/*.elf \
src/easymini-v1.0/flash-loader/*.elf \
src/easymini-v2.0/flash-loader/{*.elf,*.bin,*.map} \
+ src/easymotor-v2/flash-loader/*.elf \
src/easytimer-v1/flash-loader/*.elf \
src/telebt-v3.0/flash-loader/*.elf \
src/telebt-v4.0/flash-loader/{*.elf,*.bin,*.map} \
out.printf(",");
write_3d_accel_header();
}
+ if (has_imu) {
+ out.printf(",");
+ write_imu_header();
+ }
if (has_igniter) {
out.printf(",");
write_igniter_header();
double offset_x, offset_y;
+ int width, height;
+
public AltosLatLon lat_lon (AltosPointDouble point) {
double lat, lon;
double rads;
return screen(point(lat, lon));
}
+ /* Return first longitude value which ends up on-screen */
+ public double first_lon(double lon) {
+ /* Find a longitude left of the screen */
+ for (;;) {
+ double x = lon * scale_x - offset_x;
+ if (x < 0)
+ break;
+ lon -= 360.0;
+ }
+ /* Find the first longitude on the screen */
+ for (;;) {
+ double x = lon * scale_x - offset_x;
+ if (x >= 0)
+ break;
+ lon += 360.0;
+ }
+ return lon;
+ }
+
+ /* Return last longitude value which ends up on-screen */
+ public double last_lon(double lon) {
+ lon = first_lon(lon);
+
+ for(;;) {
+ double next_lon = lon + 360.0;
+ double next_x = next_lon * scale_x - offset_x;
+ if (next_x >= width)
+ break;
+ lon = next_lon;
+ }
+ return lon;
+ }
+
private boolean has_location;
public boolean has_location() {
scale_x = 256/360.0 * Math.pow(2, zoom);
scale_y = 256/(2.0*Math.PI) * Math.pow(2, zoom);
+ this.width = width;
+ this.height = height;
+
AltosPointDouble centre_pt = point(centre_lat_lon);
has_location = (centre_lat_lon.lat != 0 || centre_lat_lon.lon != 0);
#!/bin/bash
-#
-# Fix fonts. I don't know why the getting the
-# basename of the app set to . matters, but it does
-#
-case "$0" in
- /*)
- cd `dirname "$0"`
- ./`basename "$0"` "$@"
- exit $?
- ;;
-esac
-export FREETYPE_PROPERTIES=truetype:interpreter-version=35
##################################################################################
# #
# universalJavaApplicationStub #
# #
# @author Tobias Fischer #
# @url https://github.com/tofi86/universalJavaApplicationStub #
-# @date 2018-08-24 #
-# @version 3.0.4 #
+# @date 2021-02-21 #
+# @version 3.2.0 #
# #
##################################################################################
# #
# The MIT License (MIT) #
# #
-# Copyright (c) 2014-2018 Tobias Fischer #
+# Copyright (c) 2014-2021 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 #
# #
##################################################################################
-
+#
+# Fix fonts. I don't know why the getting the
+# basename of the app set to . matters, but it does
+#
+case "$0" in
+ /*)
+ cd `dirname "$0"`
+ ./`basename "$0"` "$@"
+ exit $?
+ ;;
+esac
+export FREETYPE_PROPERTIES=truetype:interpreter-version=35
# function 'stub_logger()'
#
JavaFolder="${AppleJavaFolder}"
ResourcesFolder="${AppleResourcesFolder}"
+ # set expandable variables
+ APP_ROOT="${AppPackageFolder}"
APP_PACKAGE="${AppPackageFolder}"
JAVAROOT="${AppleJavaFolder}"
USER_HOME="$HOME"
# 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}")
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
else
JVMDefaultOptions=${JVMDefaultOptions_RAW}
fi
+ # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#84)
+ JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")
# read StartOnMainThread and add as -XstartOnFirstThread
JVMStartOnMainThread=$(plist_get_java ':StartOnMainThread')
JVMDefaultOptions+=" -XstartOnFirstThread"
fi
- # read the JVM Arguments as an array and retain spaces
+ # read the JVM Arguments in either Array or String style (#76) and retain spaces
IFS=$'\t\n'
- MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+ MainArgs_RAW=$(plist_get_java ':Arguments' | xargs)
+ if [[ $MainArgs_RAW == *Array* ]] ; then
+ MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments' | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/ */ /g')))
+ else
+ MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+ fi
unset IFS
# post processing of the array follows further below...
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')"
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
# 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'
fi
+# (#75) check for undefined icons or icon names without .icns extension and prepare
+# an osascript statement for those cases when the icon can be shown in the dialog
+DialogWithIcon=""
+if [ ! -z ${CFBundleIconFile} ]; then
+ if [[ ${CFBundleIconFile} == *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}" ]] ; then
+ DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ elif [[ ${CFBundleIconFile} != *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}.icns" ]] ; then
+ CFBundleIconFile+=".icns"
+ DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ fi
+fi
+
# JVMVersion: post processing and optional splitting
if [[ ${JVMVersion} == *";"* ]]; then
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
# 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 Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
+ MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version de Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
MSG_NO_SUITABLE_JAVA="La version de Java installée sur votre système ne convient pas.\nCe programme nécessite Java %s"
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"
+ 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."
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"
+ 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请联系该应用的开发者。"
MSG_NO_SUITABLE_JAVA_CHECK="请确保系统中安装了所需的Java版本"
MSG_INSTALL_JAVA="你需要在Mac中安装Java运行环境!\n访问 java.com 了解如何安装。"
MSG_LATER="稍后"
- MSG_VISIT_JAVA_DOT_COM="访问 java.com"
-
-# English default localization
-else
+ MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+ MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+ ;;
+
+# 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."
+ MSG_NO_SUITABLE_JAVA="¡No se encontró una versión de Java adecuada en su sistema!\nEste programa requiere Java %s"
+ MSG_JAVA_VERSION_OR_LATER="o posterior"
+ MSG_JAVA_VERSION_LATEST="(ultima actualización)"
+ MSG_JAVA_VERSION_MAX="superior a %s"
+ MSG_NO_SUITABLE_JAVA_CHECK="Asegúrese de instalar la versión Java requerida."
+ MSG_INSTALL_JAVA="¡Necesita tener JAVA instalado en su Mac!\nVisite java.com para consultar las instrucciones para su instalación..."
+ MSG_LATER="Más tarde"
+ MSG_VISIT_JAVA_DOT_COM="Java de Oracle"
+ MSG_VISIT_ADOPTOPENJDK="Java de AdoptOpenJDK"
+ ;;
+
+# 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."
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
+ MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+ MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+ ;;
+esac
################################################################################
function is_valid_requirement_pattern() {
local java_req=$1
- java8pattern='1\.[4-8](\.0)?(\.0_[0-9]+)?[*+]?'
+ java8pattern='1\.[4-8](\.[0-9]+)?(\.0_[0-9]+)?[*+]?'
java9pattern='(9|1[0-9])(-ea|[*+]|(\.[0-9]+){1,2}[*+]?)?'
# test matches either old Java versioning scheme (up to 1.8) or new scheme (starting with 9)
if [[ ${java_req} =~ ^(${java8pattern}|${java9pattern})$ ]]; 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
- stub_logger "[JavaSearch] Checking for JavaVirtualMachines on the system ..."
+
+ # 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=""
JAVACMD_version=""
# log exit cause
stub_logger "[EXIT 4] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
# display error message with AppleScript
- osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
# exit with error
exit 4
fi
# log exit cause
stub_logger "[EXIT 5] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
# display error message with AppleScript
- osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
# exit with error
exit 5
fi
# find installed JavaVirtualMachines (JDK + JRE)
allJVMs=()
- # read JDK's from '/usr/libexec/java_home -V' command
- while read -r line; do
- version=$(echo $line | awk -F $',' '{print $1;}')
- path=$(echo $line | awk -F $'" ' '{print $2;}')
- path+="/bin/java"
- allJVMs+=("$version:$path")
- done < <(/usr/libexec/java_home -V 2>&1 | grep '^[[:space:]]')
- # unset while loop variables
- unset version path
+
+ # read JDK's from '/usr/libexec/java_home --xml' command with PlistBuddy and a custom Dict iterator
+ # idea: https://stackoverflow.com/a/14085460/1128689 and https://scriptingosx.com/2018/07/parsing-dscl-output-in-scripts/
+ javaXml=$(/usr/libexec/java_home --xml)
+ javaCounter=$(/usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< $javaXml | grep "Dict" | wc -l | tr -d ' ')
+
+ # iterate over all Dict entries
+ # 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
+ for sdkjdk in ~/.sdkman/candidates/java/*/
+ do
+ if [[ ${sdkjdk} =~ /current/$ ]] ; then
+ continue
+ fi
+
+ sdkjdkcmd="${sdkjdk}bin/java"
+ version=$(get_java_version_from_cmd "${sdkjdkcmd}")
+ allJVMs+=("$version:$sdkjdkcmd")
+ done
+ # unset for loop variables
+ unset version
+ fi
# add Apple JRE if available
if [ -x "${apple_jre_plugin}" ] ; then
# determine JVMs matching the min/max version requirement
+
+ stub_logger "[JavaSearch] Filtering the result list for JVMs matching the min/max version requirement ..."
+
minC=$(get_comparable_java_version ${JVMVersion})
maxC=$(get_comparable_java_version ${JVMMaxVersion})
matchingJVMs=()
# debug output
for i in "${matchingJVMs[@]}"
do
- stub_logger "[JavaSearch] ... ... matches all requirements: $i"
+ stub_logger "[JavaSearch] ... matches all requirements: $i"
done
stub_logger "[JavaCommand] '$JAVACMD'"
stub_logger "[JavaVersion] $(get_java_version_from_cmd "${JAVACMD}")${JAVACMD_version:+ / $JAVACMD_version}"
+# Make sure tabbing mode is disabled for the selected java version
+
+CFBundleIdentifier=net.java.openjdk.$(get_java_version_from_cmd "${JAVACMD}").java
+if [ x$(defaults read ${CFBundleIdentifier} AppleWindowTabbingMode) != "xnever" ]; then
+ defaults write ${CFBundleIdentifier} AppleWindowTabbingMode never
+fi
if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
stub_logger "[EXIT 3] ${MSG_NO_SUITABLE_JAVA_EXPANDED}"
# display error message with AppleScript
- osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\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)" \
+ osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\" buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
-e "set response to button returned of the result" \
- -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+ -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+ -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
# exit with error
exit 3
# log exit cause
stub_logger "[EXIT 1] ${MSG_ERROR_LAUNCHING}"
# 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)" \
+ 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}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
-e "set response to button returned of the result" \
- -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+ -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+ -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
# exit with error
exit 1
fi
# log exit cause
stub_logger "[EXIT 2] ${MSG_MISSING_MAINCLASS}"
# 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)"
+ 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${DialogWithIcon}"
# exit with error
exit 2
fi
# - main class
# - main class arguments
# - passthrough arguments from Terminal or Drag'n'Drop to Finder icon
-stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" -splash:\"${ResourcesFolder}/${JVMSplashFile}\" -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
+stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" ${JVMSplashFile:+ -splash:\"${ResourcesFolder}/${JVMSplashFile}\"} -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
exec "${JAVACMD}" \
-Djava.library.path="${AppleJavaFolder}" \
-cp "${JVMClassPath}" \
- -splash:"${ResourcesFolder}/${JVMSplashFile}" \
+ ${JVMSplashFile:+ -splash:"${ResourcesFolder}/${JVMSplashFile}"} \
-Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \
-Xdock:name="${CFBundleName}" \
${JVMOptionsArr:+"${JVMOptionsArr[@]}" }\
FIRMWARE_EMEGA_2_0=$(top_srcdir)/src/easymega-v2.0/easymega-v2.0-$(VERSION).ihx
FIRMWARE_EMEGA=$(FIRMWARE_EMEGA_1_0) $(FIRMWARE_EMEGA_2_0)
+FIRMWARE_EMOTOR_2=$(top_srcdir)/src/easymotor-v2/easymotor-v2-$(VERSION).ihx
+FIRMWARE_EMOTOR=$(FIRMWARE_EMOTOR_2)
+
FIRMWARE_ETIMER_1=$(top_srcdir)/src/easytimer-v1/easytimer-v1-$(VERSION).ihx
FIRMWARE_ETIMER=$(FIRMWARE_ETIMER_1)
FIRMWARE_TFIRE8_2_0=$(top_srcdir)/src/telefireeight-v2.0/telefireeight-v2.0-$(VERSION).ihx
FIRMWARE_TFIRE8=$(FIRMWARE_TFIRE8_1_0) $(FIRMWARE_TFIRE8_2_0)
-FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) $(FIRMWARE_EMINI) $(FIRMWARE_TGPS) $(FIRMWARE_EMEGA) $(FIRMWARE_ETIMER) $(FIRMWARE_TLCO) $(FIRMWARE_TFIRE8)
+FIRMWARE=$(FIRMWARE_TM) $(FIRMWARE_TELEMINI) $(FIRMWARE_TD) $(FIRMWARE_TBT) $(FIRMWARE_TMEGA) $(FIRMWARE_EMINI) $(FIRMWARE_TGPS) $(FIRMWARE_EMEGA) $(FIRMWARE_EMOTOR) $(FIRMWARE_ETIMER) $(FIRMWARE_TLCO) $(FIRMWARE_TFIRE8)
ALTUSMETRUM_DOC=$(top_srcdir)/doc/altusmetrum.pdf
ALTOS_DOC=$(top_srcdir)/doc/altos.pdf
File "../src/easymini-v2.0/easymini-v2.0-${VERSION}.ihx"
File "../src/easymega-v1.0/easymega-v1.0-${VERSION}.ihx"
File "../src/easymega-v2.0/easymega-v2.0-${VERSION}.ihx"
+ File "../src/easymotor-v2/easymotor-v2-${VERSION}.ihx"
File "../src/easytimer-v1/easytimer-v1-${VERSION}.ihx"
File "../src/telelco-v2.0/telelco-v2.0-${VERSION}.ihx"
File "../src/telefireeight-v1.0/telefireeight-v1.0-${VERSION}.ihx"
class MapMark extends AltosMapMark {
public void paint(AltosMapTransform t) {
- AltosPointDouble pt = t.screen(lat_lon);
+ double lat = lat_lon.lat;
+ double lon;
+ double first_lon = t.first_lon(lat_lon.lon);
+ double last_lon = t.last_lon(lat_lon.lon);
+ for (lon = first_lon; lon <= last_lon; lon += 360.0) {
+ AltosPointDouble pt = t.screen(lat, lon);
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
- if (0 <= state && state < AltosUIMap.stateColors.length)
- g.setColor(AltosUIMap.stateColors[state]);
- else
- g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]);
-
- g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
- g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
- g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
-
- if (label != null) {
- Rectangle2D bounds;
- bounds = line_font.getStringBounds(label, g.getFontRenderContext());
- float x = (float) pt.x;
- float y = (float) pt.y + (float) bounds.getHeight() / 2.0f;
-
- g.setFont(line_font);
- g.setColor(Color.WHITE);
- for (int dy = -2; dy <= 2; dy += 2)
- for (int dx = -2; dx <= 2; dx += 2)
- g.drawString(label, x + dx, y + dy);
if (0 <= state && state < AltosUIMap.stateColors.length)
g.setColor(AltosUIMap.stateColors[state]);
else
g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]);
- g.drawString(label, x, y);
+
+ g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
+ g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
+ g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
+
+ if (label != null) {
+ Rectangle2D bounds;
+ bounds = line_font.getStringBounds(label, g.getFontRenderContext());
+ float x = (float) pt.x;
+ float y = (float) pt.y + (float) bounds.getHeight() / 2.0f;
+
+ g.setFont(line_font);
+ g.setColor(Color.WHITE);
+ for (int dy = -2; dy <= 2; dy += 2)
+ for (int dx = -2; dx <= 2; dx += 2)
+ g.drawString(label, x + dx, y + dy);
+ if (0 <= state && state < AltosUIMap.stateColors.length)
+ g.setColor(AltosUIMap.stateColors[state]);
+ else
+ g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]);
+ g.drawString(label, x, y);
+ }
}
}
void add_mark(double lat, double lon, int state, String label) {
map.add_mark(lat, lon, state, label);
- if (lon <= 0)
- map.add_mark(lat, lon + 360, state, label);
- if (lon >= 0)
- map.add_mark(lat, lon - 360, state, label);
}
void reset_marks() {
--- /dev/null
+#!/bin/sh
+
+VERSION=2
+PRODUCT=EasyMotor
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+
+echo "$PRODUCT-v$VERSION Test Program"
+echo "Copyright 2021 by Bdale Garbee. Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo
+
+ret=1
+ao-list | while read product serial dev; do
+ case "$product" in
+ "$PRODUCT-v$VERSION")
+
+ echo "Testing $product $serial $dev"
+ echo ""
+
+ FLASHSIZE=8388608
+
+ echo "Testing flash"
+ ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE"
+
+ case $? in
+ 0)
+ ;;
+ *)
+ echo "failed"
+ exit 1
+ esac
+ echo""
+
+ echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+ ret=0
+ ;;
+ esac
+done
--- /dev/null
+#!/bin/sh
+
+PRODUCT=EasyMotor
+VERSION=2
+REPO=~/altusmetrumllc/Binaries
+
+if [ -x /usr/bin/dfu-util ]; then
+ DFU_UTIL=/usr/bin/dfu-util
+else
+ echo "Can't find dfu-util! Aborting."
+ exit 1
+fi
+
+if [ -x /usr/bin/ao-usbload ]; then
+ USBLOAD=/usr/bin/ao-usbload
+else
+ echo "Can't find ao-usbload! Aborting."
+ exit 1
+fi
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2021 by Bdale Garbee. Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION"
+echo "\t\twith USB cable attached"
+echo
+
+case $# in
+ 1)
+ SERIAL="$1"
+ echo "$PRODUCT-$VERSION serial number: $SERIAL"
+ ;;
+ 0)
+ echo -n "$PRODUCT-$VERSION serial number: "
+ read SERIAL
+ ;;
+ *)
+ echo "Usage: $0 <serial-number>" 1>&2
+ exit 1;
+ ;;
+esac
+
+
+echo $DFU_UTIL
+
+$DFU_UTIL -v -v -R -a 0 -s 0x08000000:leave -D $REPO/loaders/easymotor-v$VERSION*.elf
+
+sleep 3
+
+$USBLOAD --serial=$SERIAL $REPO/easymotor-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/'"$PRODUCT"'-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+ echo "$PRODUCT found on $dev"
+ ;;
+*)
+ echo 'No '"$PRODUCT"'-v'"$VERSION"' found'
+ exit 1
+ ;;
+esac
+
+failed=1
+while [ $failed = 1 ]; do
+ ../ao-tools/ao-cal-accel/ao-cal-accel $dev
+ failed=$?
+done
+
+./test-easymotor
+
+exit $?
file="$1"
echo "program $file verify reset" > $cmds
openocd \
- -f interface/stlink-v2.cfg \
- -f target/stm32f0x_stlink.cfg \
+ -f interface/stlink.cfg \
+ -f target/stm32f0x.cfg \
-f $cmds \
-c shutdown
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
-AC_INIT([altos], 1.9.6.1)
+AC_INIT([altos], 1.9.7)
ANDROID_VERSION=27
AC_CONFIG_SRCDIR([src/kernel/ao.h])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
-RELEASE_DATE=2020-10-29
+RELEASE_DATE=2021-04-12
AC_SUBST(RELEASE_DATE)
DOC_DATE=`LC_ALL=C date -d $RELEASE_DATE +'%d %b %Y'`
endif
RELNOTES_INC=\
+ release-notes-1.9.7.inc \
release-notes-1.9.6.inc \
release-notes-1.9.5.inc \
release-notes-1.9.4.inc \
left:
content: '{page-number}'
right:
- content: '© 2020 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License'
+ content: '© 2021 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License'
verso:
left:
content: $footer_recto_right_content
:revdate: 1 Jan 1970
:icons:
:icontype: svg
-:copyright: Bdale Garbee and Keith Packard 2020
+:copyright: Bdale Garbee and Keith Packard 2021
:doctype: book
:numbered:
:stylesheet: am.css
:easymega: 1
:telegps: 1
:easytimer: 1
+:easymotor: 1
:application: AltosUI
:pdf-stylesdir: .
:pdf-style: altusmetrum
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.7.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.6.adoc[]
=== Changing the Configuration
All available configuration options can be set using the
- "Configure Altimeter" menu selection within the AltosUI
+ “Configure Altimeter” menu selection within the AltosUI
program.
EasyMotor needs to be rigidly attached in the airframe, and the
long axis of the circuit board needs to be aligned with the axis
- of flight. By default, the round beeper on the board should be
- "up" towards the nose cone, and the screw terminal strips should
- be "down" towards the fins and motor nozzle end of the rocket.
+ of flight. By default, the round beeper on the board should be
+ “up” towards the nose cone, and the screw terminal strips should
+ be “down” towards the fins and motor nozzle end of the rocket.
=== Power Switch and Battery
- In addition to the circuit board itself, EasyMotor needs
- a power switch and battery to operate. Unlike most other
- Altus Metrum products, EasyMotor does not work with
- single-cell LiPo batteries. That's because commonly
+ In addition to the circuit board itself, EasyMotor needs
+ a power switch and battery to operate. Unlike most other
+ Altus Metrum products, EasyMotor does not work with
+ single-cell LiPo batteries. That's because commonly
available inexpensive pressure sensors need 5V, which is
- more than a single-cell LiPo provides. Any battery that
- provides from 6.5 to about 15 volts should work. Good
- choices are the common 9V alkaline battery, or the very
+ more than a single-cell LiPo provides. Any battery that
+ provides from 6.5 to about 15 volts should work. Good
+ choices are the common 9V alkaline battery, or the very
small and light A23 12V alkaline batteries.
- Because he often mounts EasyMotor to the motor's forward
- bulkhead instead of to the airframe itself, Bdale often
- uses a length of "shooter wire" from an e-match or used
- motor igniter as a power switch, routing the wire out of
- the typical fin can vent hole and using "twist and tape"
- to power up the board. Whatever works!
+ Because he often mounts EasyMotor to the motor's forward
+ bulkhead instead of to the airframe itself, Bdale often
+ uses a length of “shooter wire” from an e-match or used
+ motor igniter as a power switch, routing the wire out of
+ the typical fin can vent hole and using “twist and tape”
+ to power up the board. Whatever works!
=== Pressure Sensor
The primary motivation for designing EasyMotor was to have
a reliable way of recording motor chamber pressure during
- flight. To that end, EasyMotor supports attachment of a
- low-cost analog pressure sensor. The board provides 5V
- to power the sensor, and an input for measuring and
+ flight. To that end, EasyMotor supports attachment of a
+ low-cost analog pressure sensor. The board provides 5V
+ to power the sensor, and an input for measuring and
logging the output voltage from the sensor.
The kind of sensor EasyMotor is designed to work with
takes 5V in and has a linear analog output that ranges
from 0.5V at 0 to 4.5V at the maximum pressure supported
- by the sensor. Very inexpensive sensors that have a
- "1/8 NPT" threaded input, a "Buick-style" 3-pin connector,
- and typically ship with a short cable and mating
+ by the sensor. Very inexpensive sensors that have a
+ “1/8 NPT” threaded input, a “Buick-style” 3-pin connector,
+ and typically ship with a short cable and mating
connector, are readily available on eBay and AliExpress.
To log in-flight chamber pressure, a typical approach
- might be to drill a 1/8" sampling hole all the way
+ might be to drill a 1/8" sampling hole all the way
through the center of the motor's forward closure, then
- drill and tap partially through the closure with a "1/8
- NPT" pipe tap. Fill the touch hole with grease, screw in
- the pressure sensor, and attach the sensor leads to
+ drill and tap partially through the closure with a “1/8
+ NPT” pipe tap. Fill the touch hole with grease, screw in
+ the pressure sensor, and attach the sensor leads to
EasyMotor.
== Introduction and Overview
-Welcome to the Altus Metrum community! Our circuits and software reflect
-our passion for both hobby rocketry and Free Software. We hope their
+Welcome to the Altus Metrum community! Our circuits and software reflect
+our passion for both hobby rocketry and Free Software. We hope their
capabilities and performance will delight you in every way, but by
releasing all of our hardware and software designs under open licenses,
we also hope to empower you to take as active a role in our collective
future as you wish!
-Thank you for your interest in EasyMotor, an in-flight motor data collection
-board for hobby rockets. EasyMotor is a small circuit board that is meant
-to log motor chamber pressure and rocket acceleration during flight. With
+Thank you for your interest in motor testing products from Altus Metrum.
+Our first such product is EasyMotor, an in-flight motor data collection
+board for hobby rockets. EasyMotor is a small circuit board that is meant
+to log motor chamber pressure and rocket acceleration during flight. With
this data it's possible to determine whether a research motor is performing
-as expected. With additional information about masses and airframe drag,
+as expected. With additional information about masses and airframe drag,
it is even possible to closely estimate complete motor performance.
-With EasyMotor, the dilemma of "do I burn this on a test stand to learn more
-about how it actually works, or do I go fly it" is no more! You can fly your
+With EasyMotor, the dilemma of “do I burn this on a test stand to learn more
+about how it actually works, or do I go fly it” is no more! You can fly your
motor and get real performance data about it too!
-Because documentation is just as prone as software to contain "bugs", and
-can always be improved... If you have questions that aren't answered in this
+Because documentation is just as prone as software to contain “bugs”, and
+can always be improved… If you have questions that aren't answered in this
manual, or just need a little help figuring things out, we strongly suggest
joining the Altus Metrum user email list, which you can do by visiting
https://lists.gag.com/mailman/listinfo/altusmetrum.
== Operation
- Operating an EasyMotor board is pretty easy. Turn the power on
+ Operating an EasyMotor board is pretty easy. Turn the power on
before launch, typically during the usual pre-flight electronics
- checklist after the rocket is installed on a launch rail.
+ checklist after the rocket is installed on a launch rail.
- The board will beep out a Morse code "P" every few seconds
+ The board will beep out a Morse code “P” every few seconds
indicating that it's in pad mode and ready to detect launch.
Once launch is detected, the board logs pressure and acceleration
data 100 times per second throughout the flight.
After flight, AltosUI can be used to download the flight data,
- then export it to a comma separated values (CSV) file. Such a
+ then export it to a comma separated values (CSV) file. Such a
file can easily be loaded into a spreadsheet for analysis.
-
--- /dev/null
+= Release Notes for Version 1.9.7
+include::release-head.adoc[]
+:doctype: article
+
+ Version 1.9.7
+
+ == AltOS
+
+ * Add EasyMotor support
+
+ == AltosUI
+
+ * Add EasyMotor support
+
+ * Support Mac OS X 11 (Big Sur)
+
+ * Support Monitor Idle on Easy Timer and Easy Motor
+
+ * Fix TeleMega v4.0 configuration in Antenna Down mode.
+
+ * Show launch sites in Load Maps view
+
+ * Add IMU header names to CSV files
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.7.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.6.adoc[]
|3.7-12V
endif::easytimer[]
+ ifdef::easymotor[]
+ |EasyMotor v2.0
+ |-
+ |ADXL375 200g
+ |-
+ |-
+ |-
+ |-
+ |6.5-15V
+ endif::easymotor[]
+
|===
endif::easymega[]
ifdef::easytimer[]
- |EasyMini
+ |EasyTimer
|Debug USB Battery
|Pyro A Pyro B Battery
|0.8 inch (2.03cm)
|24mm coupler
endif::easytimer[]
+ ifdef::easymotor[]
+ |EasyMotor
+ |Debug USB
+ |+5V Pres GND Switch Battery
+ |0.8 inch (2.03cm)
+ |1½ inch (3.81cm)
+ |24mm coupler
+ endif::easymotor[]
+
|===
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.7.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.6.adoc[]
#!/bin/bash
-#
-# Fix fonts. I don't know why the getting the
-# basename of the app set to . matters, but it does
-#
-case "$0" in
- /*)
- cd `dirname "$0"`
- ./`basename "$0"` "$@"
- exit $?
- ;;
-esac
-export FREETYPE_PROPERTIES=truetype:interpreter-version=35
##################################################################################
# #
# universalJavaApplicationStub #
# #
# @author Tobias Fischer #
# @url https://github.com/tofi86/universalJavaApplicationStub #
-# @date 2018-08-24 #
-# @version 3.0.4 #
+# @date 2021-02-21 #
+# @version 3.2.0 #
# #
##################################################################################
# #
# The MIT License (MIT) #
# #
-# Copyright (c) 2014-2018 Tobias Fischer #
+# Copyright (c) 2014-2021 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 #
# #
##################################################################################
-
+#
+# Fix fonts. I don't know why the getting the
+# basename of the app set to . matters, but it does
+#
+case "$0" in
+ /*)
+ cd `dirname "$0"`
+ ./`basename "$0"` "$@"
+ exit $?
+ ;;
+esac
+export FREETYPE_PROPERTIES=truetype:interpreter-version=35
# function 'stub_logger()'
#
JavaFolder="${AppleJavaFolder}"
ResourcesFolder="${AppleResourcesFolder}"
+ # set expandable variables
+ APP_ROOT="${AppPackageFolder}"
APP_PACKAGE="${AppPackageFolder}"
JAVAROOT="${AppleJavaFolder}"
USER_HOME="$HOME"
# 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}")
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
else
JVMDefaultOptions=${JVMDefaultOptions_RAW}
fi
+ # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#84)
+ JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")
# read StartOnMainThread and add as -XstartOnFirstThread
JVMStartOnMainThread=$(plist_get_java ':StartOnMainThread')
JVMDefaultOptions+=" -XstartOnFirstThread"
fi
- # read the JVM Arguments as an array and retain spaces
+ # read the JVM Arguments in either Array or String style (#76) and retain spaces
IFS=$'\t\n'
- MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+ MainArgs_RAW=$(plist_get_java ':Arguments' | xargs)
+ if [[ $MainArgs_RAW == *Array* ]] ; then
+ MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments' | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/ */ /g')))
+ else
+ MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+ fi
unset IFS
# post processing of the array follows further below...
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')"
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
# 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'
fi
+# (#75) check for undefined icons or icon names without .icns extension and prepare
+# an osascript statement for those cases when the icon can be shown in the dialog
+DialogWithIcon=""
+if [ ! -z ${CFBundleIconFile} ]; then
+ if [[ ${CFBundleIconFile} == *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}" ]] ; then
+ DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ elif [[ ${CFBundleIconFile} != *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}.icns" ]] ; then
+ CFBundleIconFile+=".icns"
+ DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ fi
+fi
+
# JVMVersion: post processing and optional splitting
if [[ ${JVMVersion} == *";"* ]]; then
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
# 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 Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
+ MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version de Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
MSG_NO_SUITABLE_JAVA="La version de Java installée sur votre système ne convient pas.\nCe programme nécessite Java %s"
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"
+ 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."
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"
+ 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请联系该应用的开发者。"
MSG_NO_SUITABLE_JAVA_CHECK="请确保系统中安装了所需的Java版本"
MSG_INSTALL_JAVA="你需要在Mac中安装Java运行环境!\n访问 java.com 了解如何安装。"
MSG_LATER="稍后"
- MSG_VISIT_JAVA_DOT_COM="访问 java.com"
-
-# English default localization
-else
+ MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+ MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+ ;;
+
+# 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."
+ MSG_NO_SUITABLE_JAVA="¡No se encontró una versión de Java adecuada en su sistema!\nEste programa requiere Java %s"
+ MSG_JAVA_VERSION_OR_LATER="o posterior"
+ MSG_JAVA_VERSION_LATEST="(ultima actualización)"
+ MSG_JAVA_VERSION_MAX="superior a %s"
+ MSG_NO_SUITABLE_JAVA_CHECK="Asegúrese de instalar la versión Java requerida."
+ MSG_INSTALL_JAVA="¡Necesita tener JAVA instalado en su Mac!\nVisite java.com para consultar las instrucciones para su instalación..."
+ MSG_LATER="Más tarde"
+ MSG_VISIT_JAVA_DOT_COM="Java de Oracle"
+ MSG_VISIT_ADOPTOPENJDK="Java de AdoptOpenJDK"
+ ;;
+
+# 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."
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
+ MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+ MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+ ;;
+esac
################################################################################
function is_valid_requirement_pattern() {
local java_req=$1
- java8pattern='1\.[4-8](\.0)?(\.0_[0-9]+)?[*+]?'
+ java8pattern='1\.[4-8](\.[0-9]+)?(\.0_[0-9]+)?[*+]?'
java9pattern='(9|1[0-9])(-ea|[*+]|(\.[0-9]+){1,2}[*+]?)?'
# test matches either old Java versioning scheme (up to 1.8) or new scheme (starting with 9)
if [[ ${java_req} =~ ^(${java8pattern}|${java9pattern})$ ]]; 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
- stub_logger "[JavaSearch] Checking for JavaVirtualMachines on the system ..."
+
+ # 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=""
JAVACMD_version=""
# log exit cause
stub_logger "[EXIT 4] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
# display error message with AppleScript
- osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
# exit with error
exit 4
fi
# log exit cause
stub_logger "[EXIT 5] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
# display error message with AppleScript
- osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
# exit with error
exit 5
fi
# find installed JavaVirtualMachines (JDK + JRE)
allJVMs=()
- # read JDK's from '/usr/libexec/java_home -V' command
- while read -r line; do
- version=$(echo $line | awk -F $',' '{print $1;}')
- path=$(echo $line | awk -F $'" ' '{print $2;}')
- path+="/bin/java"
- allJVMs+=("$version:$path")
- done < <(/usr/libexec/java_home -V 2>&1 | grep '^[[:space:]]')
- # unset while loop variables
- unset version path
+
+ # read JDK's from '/usr/libexec/java_home --xml' command with PlistBuddy and a custom Dict iterator
+ # idea: https://stackoverflow.com/a/14085460/1128689 and https://scriptingosx.com/2018/07/parsing-dscl-output-in-scripts/
+ javaXml=$(/usr/libexec/java_home --xml)
+ javaCounter=$(/usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< $javaXml | grep "Dict" | wc -l | tr -d ' ')
+
+ # iterate over all Dict entries
+ # 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
+ for sdkjdk in ~/.sdkman/candidates/java/*/
+ do
+ if [[ ${sdkjdk} =~ /current/$ ]] ; then
+ continue
+ fi
+
+ sdkjdkcmd="${sdkjdk}bin/java"
+ version=$(get_java_version_from_cmd "${sdkjdkcmd}")
+ allJVMs+=("$version:$sdkjdkcmd")
+ done
+ # unset for loop variables
+ unset version
+ fi
# add Apple JRE if available
if [ -x "${apple_jre_plugin}" ] ; then
# determine JVMs matching the min/max version requirement
+
+ stub_logger "[JavaSearch] Filtering the result list for JVMs matching the min/max version requirement ..."
+
minC=$(get_comparable_java_version ${JVMVersion})
maxC=$(get_comparable_java_version ${JVMMaxVersion})
matchingJVMs=()
# debug output
for i in "${matchingJVMs[@]}"
do
- stub_logger "[JavaSearch] ... ... matches all requirements: $i"
+ stub_logger "[JavaSearch] ... matches all requirements: $i"
done
stub_logger "[JavaCommand] '$JAVACMD'"
stub_logger "[JavaVersion] $(get_java_version_from_cmd "${JAVACMD}")${JAVACMD_version:+ / $JAVACMD_version}"
+# Make sure tabbing mode is disabled for the selected java version
+
+CFBundleIdentifier=net.java.openjdk.$(get_java_version_from_cmd "${JAVACMD}").java
+if [ x$(defaults read ${CFBundleIdentifier} AppleWindowTabbingMode) != "xnever" ]; then
+ defaults write ${CFBundleIdentifier} AppleWindowTabbingMode never
+fi
if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
stub_logger "[EXIT 3] ${MSG_NO_SUITABLE_JAVA_EXPANDED}"
# display error message with AppleScript
- osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\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)" \
+ osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\" buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
-e "set response to button returned of the result" \
- -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+ -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+ -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
# exit with error
exit 3
# log exit cause
stub_logger "[EXIT 1] ${MSG_ERROR_LAUNCHING}"
# 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)" \
+ 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}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
-e "set response to button returned of the result" \
- -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+ -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+ -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
# exit with error
exit 1
fi
# log exit cause
stub_logger "[EXIT 2] ${MSG_MISSING_MAINCLASS}"
# 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)"
+ 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${DialogWithIcon}"
# exit with error
exit 2
fi
# - main class
# - main class arguments
# - passthrough arguments from Terminal or Drag'n'Drop to Finder icon
-stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" -splash:\"${ResourcesFolder}/${JVMSplashFile}\" -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
+stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" ${JVMSplashFile:+ -splash:\"${ResourcesFolder}/${JVMSplashFile}\"} -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
exec "${JAVACMD}" \
-Djava.library.path="${AppleJavaFolder}" \
-cp "${JVMClassPath}" \
- -splash:"${ResourcesFolder}/${JVMSplashFile}" \
+ ${JVMSplashFile:+ -splash:"${ResourcesFolder}/${JVMSplashFile}"} \
-Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \
-Xdock:name="${CFBundleName}" \
${JVMOptionsArr:+"${JVMOptionsArr[@]}" }\
ARMM3DIRS=\
easymega-v1.0 easymega-v1.0/flash-loader \
easymega-v2.0 easymega-v2.0/flash-loader \
+ easymotor-v2 easymotor-v2/flash-loader \
easytimer-v1 easytimer-v1/flash-loader \
telemega-v0.1 telemega-v0.1/flash-loader \
telemega-v1.0 telemega-v1.0/flash-loader \
#!/bin/bash
-#
-# Fix fonts. I don't know why the getting the
-# basename of the app set to . matters, but it does
-#
-case "$0" in
- /*)
- cd `dirname "$0"`
- ./`basename "$0"` "$@"
- exit $?
- ;;
-esac
-export FREETYPE_PROPERTIES=truetype:interpreter-version=35
##################################################################################
# #
# universalJavaApplicationStub #
# #
# @author Tobias Fischer #
# @url https://github.com/tofi86/universalJavaApplicationStub #
-# @date 2018-08-24 #
-# @version 3.0.4 #
+# @date 2021-02-21 #
+# @version 3.2.0 #
# #
##################################################################################
# #
# The MIT License (MIT) #
# #
-# Copyright (c) 2014-2018 Tobias Fischer #
+# Copyright (c) 2014-2021 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 #
# #
##################################################################################
-
+#
+# Fix fonts. I don't know why the getting the
+# basename of the app set to . matters, but it does
+#
+case "$0" in
+ /*)
+ cd `dirname "$0"`
+ ./`basename "$0"` "$@"
+ exit $?
+ ;;
+esac
+export FREETYPE_PROPERTIES=truetype:interpreter-version=35
# function 'stub_logger()'
#
JavaFolder="${AppleJavaFolder}"
ResourcesFolder="${AppleResourcesFolder}"
+ # set expandable variables
+ APP_ROOT="${AppPackageFolder}"
APP_PACKAGE="${AppPackageFolder}"
JAVAROOT="${AppleJavaFolder}"
USER_HOME="$HOME"
# 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}")
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
else
JVMDefaultOptions=${JVMDefaultOptions_RAW}
fi
+ # expand variables $APP_PACKAGE, $APP_ROOT, $JAVAROOT, $USER_HOME (#84)
+ JVMDefaultOptions=$(eval echo "${JVMDefaultOptions}")
# read StartOnMainThread and add as -XstartOnFirstThread
JVMStartOnMainThread=$(plist_get_java ':StartOnMainThread')
JVMDefaultOptions+=" -XstartOnFirstThread"
fi
- # read the JVM Arguments as an array and retain spaces
+ # read the JVM Arguments in either Array or String style (#76) and retain spaces
IFS=$'\t\n'
- MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+ MainArgs_RAW=$(plist_get_java ':Arguments' | xargs)
+ if [[ $MainArgs_RAW == *Array* ]] ; then
+ MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments' | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/ */ /g')))
+ else
+ MainArgs=($(xargs -n1 <<<$(plist_get_java ':Arguments')))
+ fi
unset IFS
# post processing of the array follows further below...
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')"
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
# 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'
fi
+# (#75) check for undefined icons or icon names without .icns extension and prepare
+# an osascript statement for those cases when the icon can be shown in the dialog
+DialogWithIcon=""
+if [ ! -z ${CFBundleIconFile} ]; then
+ if [[ ${CFBundleIconFile} == *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}" ]] ; then
+ DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ elif [[ ${CFBundleIconFile} != *.icns ]] && [[ -f "${ResourcesFolder}/${CFBundleIconFile}.icns" ]] ; then
+ CFBundleIconFile+=".icns"
+ DialogWithIcon=" with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ fi
+fi
+
# JVMVersion: post processing and optional splitting
if [[ ${JVMVersion} == *";"* ]]; then
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
# 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 Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
+ MSG_JVMVERSION_REQ_INVALID="La syntaxe de la version de Java demandée est invalide: %s\nVeuillez contacter le développeur de l'application."
MSG_NO_SUITABLE_JAVA="La version de Java installée sur votre système ne convient pas.\nCe programme nécessite Java %s"
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"
+ 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."
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"
+ 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请联系该应用的开发者。"
MSG_NO_SUITABLE_JAVA_CHECK="请确保系统中安装了所需的Java版本"
MSG_INSTALL_JAVA="你需要在Mac中安装Java运行环境!\n访问 java.com 了解如何安装。"
MSG_LATER="稍后"
- MSG_VISIT_JAVA_DOT_COM="访问 java.com"
-
-# English default localization
-else
+ MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+ MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+ ;;
+
+# 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."
+ MSG_NO_SUITABLE_JAVA="¡No se encontró una versión de Java adecuada en su sistema!\nEste programa requiere Java %s"
+ MSG_JAVA_VERSION_OR_LATER="o posterior"
+ MSG_JAVA_VERSION_LATEST="(ultima actualización)"
+ MSG_JAVA_VERSION_MAX="superior a %s"
+ MSG_NO_SUITABLE_JAVA_CHECK="Asegúrese de instalar la versión Java requerida."
+ MSG_INSTALL_JAVA="¡Necesita tener JAVA instalado en su Mac!\nVisite java.com para consultar las instrucciones para su instalación..."
+ MSG_LATER="Más tarde"
+ MSG_VISIT_JAVA_DOT_COM="Java de Oracle"
+ MSG_VISIT_ADOPTOPENJDK="Java de AdoptOpenJDK"
+ ;;
+
+# 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."
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
+ MSG_VISIT_JAVA_DOT_COM="Java by Oracle"
+ MSG_VISIT_ADOPTOPENJDK="Java by AdoptOpenJDK"
+ ;;
+esac
################################################################################
function is_valid_requirement_pattern() {
local java_req=$1
- java8pattern='1\.[4-8](\.0)?(\.0_[0-9]+)?[*+]?'
+ java8pattern='1\.[4-8](\.[0-9]+)?(\.0_[0-9]+)?[*+]?'
java9pattern='(9|1[0-9])(-ea|[*+]|(\.[0-9]+){1,2}[*+]?)?'
# test matches either old Java versioning scheme (up to 1.8) or new scheme (starting with 9)
if [[ ${java_req} =~ ^(${java8pattern}|${java9pattern})$ ]]; 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
- stub_logger "[JavaSearch] Checking for JavaVirtualMachines on the system ..."
+
+ # 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=""
JAVACMD_version=""
# log exit cause
stub_logger "[EXIT 4] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
# display error message with AppleScript
- osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
# exit with error
exit 4
fi
# log exit cause
stub_logger "[EXIT 5] ${MSG_JVMVERSION_REQ_INVALID_EXPANDED}"
# display error message with AppleScript
- osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1 with icon path to resource \"${CFBundleIconFile}\" in bundle (path to me)"
+ osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_JVMVERSION_REQ_INVALID_EXPANDED}\" with title \"${CFBundleName}\" buttons {\" OK \"} default button 1${DialogWithIcon}"
# exit with error
exit 5
fi
# find installed JavaVirtualMachines (JDK + JRE)
allJVMs=()
- # read JDK's from '/usr/libexec/java_home -V' command
- while read -r line; do
- version=$(echo $line | awk -F $',' '{print $1;}')
- path=$(echo $line | awk -F $'" ' '{print $2;}')
- path+="/bin/java"
- allJVMs+=("$version:$path")
- done < <(/usr/libexec/java_home -V 2>&1 | grep '^[[:space:]]')
- # unset while loop variables
- unset version path
+
+ # read JDK's from '/usr/libexec/java_home --xml' command with PlistBuddy and a custom Dict iterator
+ # idea: https://stackoverflow.com/a/14085460/1128689 and https://scriptingosx.com/2018/07/parsing-dscl-output-in-scripts/
+ javaXml=$(/usr/libexec/java_home --xml)
+ javaCounter=$(/usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< $javaXml | grep "Dict" | wc -l | tr -d ' ')
+
+ # iterate over all Dict entries
+ # 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
+ for sdkjdk in ~/.sdkman/candidates/java/*/
+ do
+ if [[ ${sdkjdk} =~ /current/$ ]] ; then
+ continue
+ fi
+
+ sdkjdkcmd="${sdkjdk}bin/java"
+ version=$(get_java_version_from_cmd "${sdkjdkcmd}")
+ allJVMs+=("$version:$sdkjdkcmd")
+ done
+ # unset for loop variables
+ unset version
+ fi
# add Apple JRE if available
if [ -x "${apple_jre_plugin}" ] ; then
# determine JVMs matching the min/max version requirement
+
+ stub_logger "[JavaSearch] Filtering the result list for JVMs matching the min/max version requirement ..."
+
minC=$(get_comparable_java_version ${JVMVersion})
maxC=$(get_comparable_java_version ${JVMMaxVersion})
matchingJVMs=()
# debug output
for i in "${matchingJVMs[@]}"
do
- stub_logger "[JavaSearch] ... ... matches all requirements: $i"
+ stub_logger "[JavaSearch] ... matches all requirements: $i"
done
stub_logger "[JavaCommand] '$JAVACMD'"
stub_logger "[JavaVersion] $(get_java_version_from_cmd "${JAVACMD}")${JAVACMD_version:+ / $JAVACMD_version}"
+# Make sure tabbing mode is disabled for the selected java version
+
+CFBundleIdentifier=net.java.openjdk.$(get_java_version_from_cmd "${JAVACMD}").java
+if [ x$(defaults read ${CFBundleIdentifier} AppleWindowTabbingMode) != "xnever" ]; then
+ defaults write ${CFBundleIdentifier} AppleWindowTabbingMode never
+fi
if [ -z "${JAVACMD}" ] || [ ! -x "${JAVACMD}" ] ; then
stub_logger "[EXIT 3] ${MSG_NO_SUITABLE_JAVA_EXPANDED}"
# display error message with AppleScript
- osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\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)" \
+ osascript -e "tell application \"System Events\" to display dialog \"${MSG_ERROR_LAUNCHING}\n\n${MSG_NO_SUITABLE_JAVA_EXPANDED}\n${MSG_NO_SUITABLE_JAVA_CHECK}\" with title \"${CFBundleName}\" buttons {\" OK \", \"${MSG_VISIT_JAVA_DOT_COM}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
-e "set response to button returned of the result" \
- -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+ -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+ -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
# exit with error
exit 3
# log exit cause
stub_logger "[EXIT 1] ${MSG_ERROR_LAUNCHING}"
# 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)" \
+ 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}\", \"${MSG_VISIT_ADOPTOPENJDK}\"} default button 1${DialogWithIcon}" \
-e "set response to button returned of the result" \
- -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"http://java.com\""
+ -e "if response is \"${MSG_VISIT_JAVA_DOT_COM}\" then open location \"https://www.java.com/download/\"" \
+ -e "if response is \"${MSG_VISIT_ADOPTOPENJDK}\" then open location \"https://adoptopenjdk.net/releases.html\""
# exit with error
exit 1
fi
# log exit cause
stub_logger "[EXIT 2] ${MSG_MISSING_MAINCLASS}"
# 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)"
+ 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${DialogWithIcon}"
# exit with error
exit 2
fi
# - main class
# - main class arguments
# - passthrough arguments from Terminal or Drag'n'Drop to Finder icon
-stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" -splash:\"${ResourcesFolder}/${JVMSplashFile}\" -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
+stub_logger "[Exec] \"$JAVACMD\" -cp \"${JVMClassPath}\" ${JVMSplashFile:+ -splash:\"${ResourcesFolder}/${JVMSplashFile}\"} -Xdock:icon=\"${ResourcesFolder}/${CFBundleIconFile}\" -Xdock:name=\"${CFBundleName}\" ${JVMOptionsArr:+$(printf "'%s' " "${JVMOptionsArr[@]}") }${JVMDefaultOptions:+$JVMDefaultOptions }${JVMMainClass}${MainArgsArr:+ $(printf "'%s' " "${MainArgsArr[@]}")}${ArgsPassthru:+ $(printf "'%s' " "${ArgsPassthru[@]}")}"
exec "${JAVACMD}" \
-Djava.library.path="${AppleJavaFolder}" \
-cp "${JVMClassPath}" \
- -splash:"${ResourcesFolder}/${JVMSplashFile}" \
+ ${JVMSplashFile:+ -splash:"${ResourcesFolder}/${JVMSplashFile}"} \
-Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \
-Xdock:name="${CFBundleName}" \
${JVMOptionsArr:+"${JVMOptionsArr[@]}" }\