From 1137fc81f4e897aa135ca2237cfecb38acdb5d9b Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Thu, 1 Aug 2024 15:30:15 +0100 Subject: [PATCH] JAL-3631 Separated jalview.sh and update.sh, and included in install4j installer and macos DMG. --- build.gradle | 12 +- gradle.properties | 3 + utils/getdown/bin/jalview.ps1 | 109 ++++------- utils/getdown/bin/jalview.sh | 234 +++++++----------------- utils/getdown/bin/update.bat | 50 +++++ utils/getdown/bin/update.ps1 | 148 +++++++++++++++ utils/getdown/bin/update.sh | 232 +++++++++++++++++++++++ utils/install4j/install4j10_template.install4j | 129 +++++++++++-- 8 files changed, 660 insertions(+), 257 deletions(-) create mode 100644 utils/getdown/bin/update.bat create mode 100644 utils/getdown/bin/update.ps1 create mode 100755 utils/getdown/bin/update.sh diff --git a/build.gradle b/build.gradle index e0d7aed..87e4ced 100644 --- a/build.gradle +++ b/build.gradle @@ -2388,7 +2388,14 @@ task getdownWebsiteBuild() { } } - def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ] + def getdownWrapperScripts = [ + getdown_bash_wrapper_script, + getdown_powershell_wrapper_script, + getdown_batch_wrapper_script, + getdown_bash_update_script, + getdown_powershell_update_script, + getdown_batch_update_script + ] getdownWrapperScripts.each{ script -> def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" ) if (s.exists()) { @@ -3025,6 +3032,9 @@ task installerFiles(type: com.install4j.gradle.Install4jTask) { 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script, 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script, 'BATCH_WRAPPER_SCRIPT': getdown_batch_wrapper_script, + 'BASH_UPDATE_SCRIPT': getdown_bash_update_script, + 'POWERSHELL_UPDATE_SCRIPT': getdown_powershell_update_script, + 'BATCH_UPDATE_SCRIPT': getdown_batch_update_script, 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir, 'MACOSARCHIVE_X64_NAME': install4jmacOSArchiveX64Name, 'MACOSARCHIVE_AARCH64_NAME': install4jmacOSArchiveAarch64Name, diff --git a/gradle.properties b/gradle.properties index 0b722ef..23d745a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -166,6 +166,9 @@ getdown_wrapper_script_dir = bin getdown_bash_wrapper_script = jalview.sh getdown_powershell_wrapper_script = jalview.ps1 getdown_batch_wrapper_script = jalview.bat +getdown_bash_update_script = update.sh +getdown_powershell_update_script = update.ps1 +getdown_batch_update_script = update.bat OSX_KEYSTORE = OSX_KEYPASS = diff --git a/utils/getdown/bin/jalview.ps1 b/utils/getdown/bin/jalview.ps1 index d57b1de..edf0e49 100755 --- a/utils/getdown/bin/jalview.ps1 +++ b/utils/getdown/bin/jalview.ps1 @@ -16,41 +16,34 @@ if ( $IsWindows -eq $null ) { $myIsMacOS = $IsMacOS } -# are we running an update -[bool] $update = 0 -[bool] $updateuser = 0 -[bool] $updateinstallation = 0 [bool] $headless = 0 -[bool] $help = 0 [bool] $gui = 0 +[bool] $help = 0 [bool] $debug = 0 -for ( $i = 0; $i -lt $args.count; $i++ ) { - if ( $args[$i] -eq "--updateuser" ) { - $update = 1 - $updateuser = 1 - $headless = 1 - } - if ( $args[$i] -eq "--updateinstallation" ) { - $update = 1 - $updateinstallation = 1 - $headless = 1 - } - if ( $args[$i] -eq "--help" -or $args[$i].StartsWith("--help-") -or $args[$i] -eq "--version" -or $args[$i] -eq "-h" ) { +Switch -Regex ($args) { + "--help|--help-|--version|-h" { $help = 1 $headless = 1 + Continue } - if ( $args[$i] -eq "--gui" ) { + "--gui" { $gui = 1 + Continue + } + "--headless" { + $headless = 1 + Continue } - if ( $args[$i] -eq "--debug" ) { + "--debug" { $debug = 1 + Continue } } if ( $help ) { - $gui = 0 -} elseif ( $update ) { + # --help takes precedence $gui = 0 } elseif ( $gui ) { + # --gui takes precedence over --headless $headless = 0 } @@ -90,15 +83,16 @@ if ( $MyInvocation.MyCommand.Path -eq $null ) { throw "Script or link to script must have extension .ps1" } +# args for the JVM +$JVMARGS = @() + $CMDPATH = ( Get-Item $MyInvocation.MyCommand.Path ) $SCRIPTPATH = Readlink-f -Link $CMDPATH $SCRIPT = $SCRIPTPATH $DIR = Split-Path -Path $SCRIPTPATH -Parent - $APPDIR = If ( ( Split-Path -Path $DIR -Leaf ) -eq "bin" ) { Split-Path -Path $DIR -Parent } Else { $DIR } $JAVAEXE = If ( $myIsWindows ) { "java.exe" } Else { "java" } $JAVA = Join-Path -Path $APPDIR -ChildPath ( "jre/" + $( If ( $myIsMacOS ) { "Contents/Home/" } Else { "" } ) + "bin/${JAVAEXE}" ) -$JVMARGS = @() if ( $headless ) { # not setting java.awt.headless in java invocation of running jalview due to problem with Jmol @@ -112,63 +106,35 @@ if ( $headless ) { } $GETDOWNTXT = Join-Path -Path $APPDIR -ChildPath "getdown.txt" -$GETDOWNJAR = Join-Path -Path $APPDIR -ChildPath "getdown-launcher.jar" -# look for bundled JRE. Might not be there if unix installer used in which case just invoke "java" -if ( -not ( Test-Path -Path "${JAVA}" ) ) { - Write-Host "Cannot find bundled ${JAVAEXE}. Using system ${JAVAEXE} and hoping for the best!" - $JAVA = $JAVAEXE +# look for getdown.txt -- needed to create classpath +if ( -not ( Test-Path -Path "${GETDOWNTXT}" ) ) { + throw "Cannot find ${GETDOWNTXT}" } +# launching Jalview with jalview.bin.Launcher instead of getdown-launcher.jar $CLASS = "jalview.bin.Launcher" -if ( $update ) { - - # JUST RUNNING A GETDOWN INSTALLATION UPDATE, not launching Jalview - $CLASS = "com.threerings.getdown.launcher.GetdownApp" - - $CLASSPATH = $GETDOWNJAR - - # installation update - if ( $updateinstallation ) { - $JVMARGS += "-Dnouserdefaultappdir=true" - } - - # tell getdown to update jalview without launching - $JVMARGS += "-Dsilent=true" - $JVMARGS += "-Dlauncher.script=${SCRIPT}" - $JVMARGS += "-Dlauncher.update=true" - $JVMARGS += "-Dappid=jalview" - $JVMARGS += "-Dinstaller.appdir=${APPDIR}" - # resetting ARGS to just these two values - $myArgs = @("${APPDIR}", "jalview") - # add these Just In Case although jalview shouldn't be launched - $myArgs += "--headless", "--quit", "--nojavaconsole", "--nosplash", "--nonews" -} else { - - # LAUNCHING JALVIEW without getdown-launcher - $CLASS = "jalview.bin.Launcher" - # look for getdown.txt -- needed to create classpath - if ( -not ( Test-Path -Path "${GETDOWNTXT}" ) ) { - throw "Cannot find ${GETDOWNTXT}" - } - # get CLASSPATH from the code= entries in getdown.txt - $CLASSPATH = ( Select-String -Path "${GETDOWNTXT}" -AllMatches -Pattern "code\s*=\s*(.*)$" | foreach { Join-Path -Path $APPDIR -ChildPath $($_.Matches.Groups[1].Value ) } ) -join $( If ( $myIsWindows ) { ";" } Else { ":" } ) +# get CLASSPATH from the code= entries in getdown.txt +$CLASSPATH = ( Select-String -Path "${GETDOWNTXT}" -AllMatches -Pattern "code\s*=\s*(.*)$" | foreach { Join-Path -Path $APPDIR -ChildPath $($_.Matches.Groups[1].Value ) } ) -join $( If ( $myIsWindows ) { ";" } Else { ":" } ) - # get console width - $CONSOLEWIDTH = $Host.UI.RawUI.WindowSize.Width - $JVMARGS += "-DCONSOLEWIDTH=${CONSOLEWIDTH}" - $JVMARGS += "-Dgetdownappdir=${APPDIR}" - $JVMARGS += "-Dinstaller.appdir=${APPDIR}" - $JVMARGS += "-Dlauncher.appdir=${APPDIR}" - $JVMARGS += "-Dlauncher.script=${SCRIPT}" +# get console width +$COLUMNS = $Host.UI.RawUI.WindowSize.Width +$JVMARGS += "-DCONSOLEWIDTH=${COLUMNS}" +$JVMARGS += "-Dgetdownappdir=${APPDIR}" +$JVMARGS += "-Dinstaller.appdir=${APPDIR}" +$JVMARGS += "-Dlauncher.script=${SCRIPT}" +# look for bundled JRE. Might not be there if unix installer used in which case just invoke "java" +if ( -not ( Test-Path -Path "${JAVA}" ) ) { + Write-Host "Cannot find bundled ${JAVA}. Using system ${JAVAEXE} and hoping for the best!" + $JAVA = $JAVAEXE } -# we should always have at least one JVMARGS +# we should always have at least one JVMARGS so this is okay $myJvmArgsString = '"' + $($JVMARGS -join '" "') + '"' -# quote the args and the command (in case of spaces) with escape chars (`) and precede with & to indicate command not string +# quote the args and the command (in case of spaces) with escape chars (`) and precede with & to indicate a command not string if ( $myArgs.count -eq 0 ) { $COMMAND = "& `"${JAVA}`" ${myJvmArgsString} -cp `"${CLASSPATH}`" $CLASS" } else { @@ -182,8 +148,3 @@ if ( $debug -or $help ) { Invoke-Expression -Command ${COMMAND} -# move updated getdown-launcher.jar into place -if ( $update ) - Invoke-Expression -Command "& `"${JAVA}`" ${myJvmArgString} -cp `"${GDCOREPATH}`" jalview.bin.GetdownUpdate `"${APPDIR}`" -fi - diff --git a/utils/getdown/bin/jalview.sh b/utils/getdown/bin/jalview.sh index 58a13d8..95e6fae 100755 --- a/utils/getdown/bin/jalview.sh +++ b/utils/getdown/bin/jalview.sh @@ -2,34 +2,6 @@ declare -a ARGS=("${@}") -# this whole next part is because there's no readlink -f in Darwin -function readlinkf() { - FINDFILE="$1" - FILE="${FINDFILE}" - PREVFILE="" - C=0 - MAX=100 # just in case we end up in a loop - FOUND=0 - while [ "${C}" -lt "${MAX}" -a "${FILE}" != "${PREVFILE}" -a "${FOUND}" -ne 1 ]; do - PREVFILE="${FILE}" - FILE="$(readlink "${FILE}")" - if [ -z "${FILE}" ]; then - # the readlink is empty means we've arrived at the script, let's canonicalize with pwd - FILE="$(cd "$(dirname "${PREVFILE}")" &> /dev/null && pwd -P)"/"$(basename "${PREVFILE}")" - FOUND=1 - elif [ "${FILE#/}" = "${FILE}" ]; then - # FILE is not an absolute path link, we need to add the relative path to the previous dir - FILE="$(dirname "${PREVFILE}")/${FILE}" - fi - C=$((C+1)) - done - if [ "${FOUND}" -ne 1 ]; then - echo "Could not determine path to actual file '$(basename "${FINDFILE}")'" >&2 - exit 1 - fi - echo "${FILE}" -} - ISMACOS=0 if [ "$( uname -s )" = "Darwin" ]; then ISMACOS=1 @@ -40,9 +12,6 @@ HEADLESS=0 GUI=0 HELP=0 DEBUG=0 -UPDATE=0 -UPDATEUSER=0 -UPDATEINSTALLATION=0 for RAWARG in "${@}"; do ARG="${RAWARG%%=*}" case "${ARG}" in @@ -59,29 +28,44 @@ for RAWARG in "${@}"; do --debug) DEBUG=1 ;; - --updateinstallation) - UPDATE=1 - UPDATEINSTALLATION=1 - HEADLESS=1 - ;; - --updateuser) - UPDATE=1 - UPDATEUSER=1 - HEADLESS=1 - ;; esac done if [ "${HELP}" = 1 ]; then # --help takes precedence GUI=0 -elif [ "${UPDATE}" = 1 ]; then - # --update takes precedence over everything else, we don't run jalview! - GUI=0 elif [ "${GUI}" = 1 ]; then # --gui takes precedence over --headless HEADLESS=0 fi +# this whole next part is because there's no readlink -f in Darwin +function readlinkf() { + FINDFILE="$1" + FILE="${FINDFILE}" + PREVFILE="" + C=0 + MAX=100 # just in case we end up in a loop + FOUND=0 + while [ "${C}" -lt "${MAX}" -a "${FILE}" != "${PREVFILE}" -a "${FOUND}" -ne 1 ]; do + PREVFILE="${FILE}" + FILE="$(readlink "${FILE}")" + if [ -z "${FILE}" ]; then + # the readlink is empty means we've arrived at the script, let's canonicalize with pwd + FILE="$(cd "$(dirname "${PREVFILE}")" &> /dev/null && pwd -P)"/"$(basename "${PREVFILE}")" + FOUND=1 + elif [ "${FILE#/}" = "${FILE}" ]; then + # FILE is not an absolute path link, we need to add the relative path to the previous dir + FILE="$(dirname "${PREVFILE}")/${FILE}" + fi + C=$((C+1)) + done + if [ "${FOUND}" -ne 1 ]; then + echo "Could not determine path to actual file '$(basename "${FINDFILE}")'" >&2 + exit 1 + fi + echo "${FILE}" +} + # args for the JVM declare -a JVMARGS=() @@ -91,22 +75,18 @@ if [ "${ISMACOS}" = 1 ]; then SCRIPT="$(readlinkf "$0")" DIR="$(dirname "${SCRIPT}")" APPDIR="${DIR%/bin}" - JAVA="${APPDIR}/jre/Contents/Home/bin/java" + JAVABIN="${APPDIR}/jre/Contents/Home/bin" + JAVA="${JAVABIN}/java" if [ "${HEADLESS}" != 1 ]; then JVMARGS=( "${JVMARGS[@]}" "-Xdock:icon=${APPDIR}/resource/jalview_logo.png" ) fi - # e.g. APPFOLDER=/Applications/Jalview.app - APPFOLDER="${APPDIR%%.app/*}.app" - VMOPTIONS="${APPFOLDER}/Contents/vmoptions.txt" else # NOT MACOS SCRIPT="$(readlink -f "$0")" DIR="$(dirname "${SCRIPT}")" APPDIR="${DIR%/bin}" - JAVA="${APPDIR}/jre/bin/java" - # e.g. APPFOLDER=/opt/jalview - APPFOLDER="${APPDIR}" - VMOPTIONS="${APPDIR}/jalviewg.vmoptions" + JAVABIN="${APPDIR}/jre/bin" + JAVA="${JAVABIN}/java" fi # headless java arguments @@ -123,124 +103,46 @@ fi SYSJAVA=java GETDOWNTXT="${APPDIR}/getdown.txt" -GETDOWNJAR="${APPDIR}/getdown-launcher.jar" CHANNELPROPS="${APPDIR}/channel.props" -NAME="$( grep app_name= App/channel.props | cut -d= -f2 )" -US_NAME="${NAME// /_}" +NAME="$( grep app_name= "${CHANNELPROPS}" | cut -d= -f2 )" CLASSPATH="" # save an array of JAR paths in case we're in WSL (see later) declare -a JARPATHS=() -declare -a APPJARPATHS=() -GDCOREPATH="${APPDIR}/resource/getdown-core.jar" -# get classpath from getdown.txt -if [ -e "${GETDOWNTXT}" ]; then - # always check grep and sed regexes on macos -- they're not the same - for JAR in $(grep -e '^code[[:space:]]*=[[:space:]]*' "${GETDOWNTXT}" | while read -r line; do echo $line | sed -E -e 's/code[[:space:]]*=[[:space:]]*//;'; done); - do - [ -n "${CLASSPATH}" ] && CLASSPATH="${CLASSPATH}:" - CLASSPATH="${CLASSPATH}${APPDIR}/${JAR}" - APPJARPATHS=( "${APPJARPATHS[@]}" "${APPDIR}/${JAR}" ) - if [ "${JAR}" != "${JAR%getdown-core.jar}" -a \! -e "${GDCOREPATH}" ]; then - GDCOREPATH="${APPDIR}/${JAR}" - fi - done -else - echo "Cannot find getdown.txt" >&2 +# look for getdown.txt -- needed to create classpath +if [ \! -e "${GETDOWNTXT}" ]; then + echo "Cannot find ${GETDOWNTXT}" >&2 exit 3 fi -CLASS="jalview.bin.Launcher" # set as default Just In Case -if [ "${UPDATE}" = 1 ]; then - - # GETDOWN UPDATE ONLY, not launching Jalview - CLASS="com.threerings.getdown.launcher.GetdownApp" - if [ -e "${GETDOWNJAR}" ]; then - CLASSPATH="${GETDOWNJAR}" - JARPATHS=( "${JARPATHS[@]}" "${GETDOWNJAR}" ) - else - echo "Cannot find getdown-launcher.jar to run update" >&2 - exit 13 - fi +# launching Jalview with jalview.bin.Launcher instead of getdown-launcher.jar +CLASS="jalview.bin.Launcher" - # USER space update - if [ "${UPDATEUSER}" = 1 ]; then - if [ -e "${VMOPTIONS}" ]; then - LINENUM=0 - while IFS= read -r line; do - # remove comments - line=${line%%#*} - # remove trailing whitespace - line="${line%"${line##*[![:space:]]}"}" - LINENUM=$((LINENUM+1)) - - # add settings for user appdir - if [ "${line}" != "${line#-Dsetuserappdirpath=}" ]; then # starts with -Dsetuserappdirpath= - JVMARGS=( "${JVMARGS[@]}" "${line}" ) - fi - if [ "${line}" != "${line#-Dnouserdefaultappdir=}" ]; then # starts with -Dnouserdefaultappdir= - # don't perform user update if user updates are disabled - NOUSERUPDATEVALUE="$(echo "${line#-Dnouserdefaultappdir=}" | tr '[:upper:]' '[:lower:]')" - if [ "${NOUSERUPDATEVALUE}" = "true" ]; then - echo "Cannot perform manual user-space update when user-space updates are disabled." >&2 - echo "See line ${LINENUM} (${line}) in file '${VMOPTIONS}'." >&2 - exit 14 - fi - JVMARGS=( "${JVMARGS[@]}" "${line}" ) - fi - done < "${VMOPTIONS}" - fi - JVMARGS=( "${JVMARGS[@]}" "-Duserdefaultappdir=true" ) - # resetting ARGS to just these two blank values so userappdir is determined - ARGS=( "" "jalview" ) - fi - - # INSTALLATION update - if [ "${UPDATEINSTALLATION}" = 1 ]; then - JVMARGS=( "${JVMARGS[@]}" "-Dnouserdefaultappdir=true" ) - JVMARGS=( "${JVMARGS[@]}" "-Dlauncher.appdir=${APPDIR}" ) - # resetting ARGS to just these two values - ARGS=( "${APPDIR}" "jalview" ) - fi - - # both USER and INSTALLATION updates - JVMARGS=( "${JVMARGS[@]}" "-Dinstaller.appdir=${APPDIR}" ) - - # tell getdown to update jalview withouth launching - JVMARGS=( "${JVMARGS[@]}" "-Dsilent=true" ) - - JVMARGS=( "${JVMARGS[@]}" "-Dlauncher.update=true" ) - JVMARGS=( "${JVMARGS[@]}" "-Dappid=jalview" ) - JVMARGS=( "${JVMARGS[@]}" "-Dchannel.app_name=${NAME}" ) - JVMARGS=( "${JVMARGS[@]}" "-Dinstaller.application_folder=${US_NAME}" ) - - # add these Just In Case although jalview shouldn't be launched due to -Dsilent=true - ARGS=( "${ARGS[@]}" "--headless" "--quit" "--nojavaconsole" "--nosplash" "--nonews" ) - -else - - # LAUNCHING JALVIEW without getdown-launcher - CLASS="jalview.bin.Launcher" - JARPATHS="${APPJARPATHS[@]}" - - COLUMNS=80 - # get console width -- three ways to try, just in case (not needed for update) - if command -v tput 2>&1 >/dev/null; then - COLUMNS=$(tput cols) 2>/dev/null - elif command -v stty 2>&1 >/dev/null; then - COLUMNS=$(stty size | cut -d" " -f2) 2>/dev/null - elif command -v resize 2>&1 >/dev/null; then - COLUMNS=$(resize -u | grep COLUMNS= | sed -e 's/.*=//;s/;//') 2>/dev/null - fi - - JVMARGS=( "${JVMARGS[@]}" "-DCONSOLEWIDTH=${COLUMNS}" ) - JVMARGS=( "${JVMARGS[@]}" "-Dgetdownappdir=${APPDIR}" ) +# get classpath from the code= entries in getdown.txt +# always check grep and sed regexes on macos -- they're not the same +for JAR in $(grep -e '^code[[:space:]]*=[[:space:]]*' "${GETDOWNTXT}" | while read -r line; do echo $line | sed -E -e 's/code[[:space:]]*=[[:space:]]*//;'; done); +do + [ -n "${CLASSPATH}" ] && CLASSPATH="${CLASSPATH}:" + CLASSPATH="${CLASSPATH}${APPDIR}/${JAR}" + JARPATHS=( "${JARPATHS[@]}" "${APPDIR}/${JAR}" ) +done +COLUMNS=80 +# get console width -- three ways to try, just in case (not needed for update) +if command -v tput 2>&1 >/dev/null; then + COLUMNS=$(tput cols) 2>/dev/null +elif command -v stty 2>&1 >/dev/null; then + COLUMNS=$(stty size | cut -d" " -f2) 2>/dev/null +elif command -v resize 2>&1 >/dev/null; then + COLUMNS=$(resize -u | grep COLUMNS= | sed -e 's/.*=//;s/;//') 2>/dev/null fi +JVMARGS=( "${JVMARGS[@]}" "-DCONSOLEWIDTH=${COLUMNS}" ) +JVMARGS=( "${JVMARGS[@]}" "-Dgetdownappdir=${APPDIR}" ) JVMARGS=( "${JVMARGS[@]}" "-Dlauncher.script=${SCRIPT}" ) JVMARGS=( "${JVMARGS[@]}" "-Dinstaller.appdir=${APPDIR}" ) +JAVAEXT="" # WINDOWS ONLY in Cygwin or Windows Subsystem for Linux (WSL) # change paths for Cygwin or WSL if [ "${ISMACOS}" != 1 ]; then # older macos doesn't like uname -o, best to avoid @@ -274,14 +176,19 @@ if [ "${ISMACOS}" != 1 ]; then # older macos doesn't like uname -o, best to avoi ARGS=( "${ARGS[@]}" "${ARG}" ) fi done - JAVA="${JAVA}.exe" - SYSJAVA="java.exe" + JAVAEXT=".exe" + JAVA="${JAVA}${JAVAEXT}" + SYSJAVA="java${JAVAEXT}" fi fi -# Is there a bundled Java? If not just try one in the PATH (we need .exe in WSL, added above) +# look for bundled JRE. Might not be there if unix installer used in which case just invoke "java" +if [ -e "${JAVABIN}/${NAME}${JAVAEXT}" ]; then + JAVA="${JAVABIN}/${NAME}${JAVAEXT}" +fi +# If not just try one in the PATH (we need .exe in WSL, added above) if [ \! -e "${JAVA}" ]; then - JAVA=$SYSJAVA + JAVA="${SYSJAVA}" echo "Cannot find bundled ${JAVA}, using system ${SYSJAVA} and hoping for the best!" >&2 fi @@ -297,6 +204,7 @@ function quotearray() { echo $QUOTEDVALS } +# for the debug command display JVMARGSSTR=$(quotearray "${JVMARGS[@]}") ARGSSTR=$(quotearray "${ARGS[@]}") @@ -305,11 +213,3 @@ if [ "${DEBUG}" = 1 ]; then fi "${JAVA}" "${JVMARGS[@]}" -cp "${CLASSPATH}" "${CLASS}" "${ARGS[@]}" - -# move updated getdown-launcher.jar into place -if [ "${DEBUG}" = 1 ]; then - echo Shell running: \""${JAVA}"\" ${JVMARGSSTR} -cp \""${GDCOREPATH}"\" jalview.bin.GetdownLauncherUpdate >&2 -fi -if [ "${UPDATE}" = 1 ]; then - "${JAVA}" "${JVMARGS[@]}" -cp "${GDCOREPATH}" jalview.bin.GetdownLauncherUpdate -fi diff --git a/utils/getdown/bin/update.bat b/utils/getdown/bin/update.bat new file mode 100644 index 0000000..c88225d --- /dev/null +++ b/utils/getdown/bin/update.bat @@ -0,0 +1,50 @@ +@ECHO OFF + +REM This is the Jalview batch script wrapper to run the powershell script of the same name. +REM There is nothing specific to Jalview. + +REM ****************************************************************************** +REM If you need to set a full path to the PowerShell executable please do so here: +SET PWSHPATH= +REM ****************************************************************************** + +REM This is some DOS magic to substitute the extension in the full path of this batch script with .ps1 +SET SCRIPTPATH=%~dpn0.ps1 + +REM PowerShell script isn't where it should be! +IF NOT EXIST "%SCRIPTPATH%" ( + ECHO Could not find PowerShell script "%SCRIPTPATH%". Is %~nx0 in the right folder? + EXIT /B 1 +) + +REM Look for either pwsh.exe or powershell.exe if not set in PWSHPATH above. +REM pwsh.exe is preferred as it is likely to be a newer version. +SET PWSH= +IF DEFINED PWSHPATH ( + SET PWSH=%PWSHPATH% +) +FOR %%X IN (pwsh.exe powershell.exe) DO ( + IF NOT DEFINED PWSH ( + IF NOT "%%~$PATH:X" == "" ( + REM Found a PowerShell executable in the PATH + SET PWSH="%%X" + GOTO end_looking + ) + ) +) +:end_looking + +IF NOT DEFINED PWSH ( + REM No PowerShell executable found -- tell the user what to do. + ECHO No PowerShell found in %%PATH%%. If PowerShell is installed either + ECHO 1. add it to your PATH, or + ECHO 2. edit the PWSHPATH value at the top of this file: + ECHO "%~dpnx0" + ECHO. + ECHO %~n0 on the command line requires PowerShell. To install PowerShell see + ECHO https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell + EXIT /B 2 +) + +REM Run the PowerShell script +"%PWSH%" -NoProfile -ExecutionPolicy Bypass -Command "& '%SCRIPTPATH%' %*"; diff --git a/utils/getdown/bin/update.ps1 b/utils/getdown/bin/update.ps1 new file mode 100644 index 0000000..4914dd8 --- /dev/null +++ b/utils/getdown/bin/update.ps1 @@ -0,0 +1,148 @@ +#!/usr/bin/env pwsh + +# save args and first parameter +$myArgs = $args.Clone() +$myArg1 = $args[0] + +# setup for powershell version < 6.0 +[bool] $myIsWindows = 0 +[bool] $myIsMacOS = 0 +if ( $IsWindows -eq $null ) { + # for powershell version < 6.0 let's assume Windows + $myIsWindows = 1 + $myIsMacOS = 0 +} else { + $myIsWindows = $IsWindows + $myIsMacOS = $IsMacOS +} + +[bool] $headless = 0 +[bool] $gui = 0 +[bool] $help = 0 +[bool] $debug = 0 +Switch -Regex ($args) { + "--help|--help-|--version|-h" { + $help = 1 + $headless = 1 + Continue + } + "--gui" { + $gui = 1 + Continue + } + "--headless" { + $headless = 1 + Continue + } + "--debug" { + $debug = 1 + Continue + } +} +if ( $help ) { + # --help takes precedence + $gui = 0 +} elseif ( $gui ) { + # --gui takes precedence over --headless + $headless = 0 +} + +# parent dir of this actual script (which should be the getdown appdir/bin). Follow all symlinks. Like GNU readlink -f +function Readlink-f { + Param($Link) + $Return = $null + $c = 0 + $max = 100 # just in case we end up in a loop + [bool] $found = 0 + $file = Get-Item -Path $Link + $prevfile = $null + While ( $c -lt $max -and "${file}" -ne "${prevfile}" -and -not $found ) { + $prevfile = $file + [string] $target = ( $file ).Target + If ( $target -eq $null -or ( $file ).LinkType -ne "SymbolicLink" ) { + $Return = $file + $found = 1 + } Else { + If ( $( Split-Path -Path $target -IsAbsolute ) ) { + $file = Get-Item -Path $target + } Else { +# symbolic link is relative: combine previous link parent dir with the link target and resolve + $file = Get-Item -Path ( Join-Path -Path ( Split-Path -Path $prevfile -Parent ) -ChildPath $target -Resolve ) + } + } + $c++ + } + if ( -not $found ) { + throw "Could not determine path to actual file $( Split-Path -Path $Link -Leaf )" + } + $Return +} + +# Avert problem with unix version of powershell and tell user the reason (Windows must always have .ps1 extension) +if ( $MyInvocation.MyCommand.Path -eq $null ) { + throw "Script or link to script must have extension .ps1" +} + +$CMDPATH = ( Get-Item $MyInvocation.MyCommand.Path ) +$SCRIPTPATH = Readlink-f -Link $CMDPATH +$SCRIPT = $SCRIPTPATH +$DIR = Split-Path -Path $SCRIPTPATH -Parent + +$APPDIR = If ( ( Split-Path -Path $DIR -Leaf ) -eq "bin" ) { Split-Path -Path $DIR -Parent } Else { $DIR } +$JAVAEXE = If ( $myIsWindows ) { "java.exe" } Else { "java" } +$JAVA = Join-Path -Path $APPDIR -ChildPath ( "jre/" + $( If ( $myIsMacOS ) { "Contents/Home/" } Else { "" } ) + "bin/${JAVAEXE}" ) +$JVMARGS = @() + +if ( $headless ) { + # not setting java.awt.headless in java invocation of running jalview due to problem with Jmol + if ( $help ) { + $JVMARGS += "-Djava.awt.headless=true" + } + # this suppresses the Java icon appearing in the macOS Dock + if ( $myIsMacOS ) { + $JVMARGS += "-Dapple.awt.UIElement=true" + } +} + +$GETDOWNTXT = Join-Path -Path $APPDIR -ChildPath "getdown.txt" + +# look for bundled JRE. Might not be there if unix installer used in which case just invoke "java" +if ( -not ( Test-Path -Path "${JAVA}" ) ) { + Write-Host "Cannot find bundled ${JAVA}. Using system ${JAVAEXE} and hoping for the best!" + $JAVA = $JAVAEXE +} + +# launching Jalview with jalview.bin.Launcher instead of getdown-launcher.jar +$CLASS = "jalview.bin.Launcher" +# look for getdown.txt -- needed to create classpath +if ( -not ( Test-Path -Path "${GETDOWNTXT}" ) ) { + throw "Cannot find ${GETDOWNTXT}" +} +# get CLASSPATH from the code= entries in getdown.txt +$CLASSPATH = ( Select-String -Path "${GETDOWNTXT}" -AllMatches -Pattern "code\s*=\s*(.*)$" | foreach { Join-Path -Path $APPDIR -ChildPath $($_.Matches.Groups[1].Value ) } ) -join $( If ( $myIsWindows ) { ";" } Else { ":" } ) + +# get console width +$COLUMNS = $Host.UI.RawUI.WindowSize.Width +$JVMARGS += "-DCONSOLEWIDTH=${COLUMNS}" +$JVMARGS += "-Dgetdownappdir=${APPDIR}" +$JVMARGS += "-Dinstaller.appdir=${APPDIR}" +$JVMARGS += "-Dlauncher.appdir=${APPDIR}" +$JVMARGS += "-Dlauncher.script=${SCRIPT}" + +# we should always have at least one JVMARGS so this is okay +$myJvmArgsString = '"' + $($JVMARGS -join '" "') + '"' + +# quote the args and the command (in case of spaces) with escape chars (`) and precede with & to indicate a command not string +if ( $myArgs.count -eq 0 ) { + $COMMAND = "& `"${JAVA}`" ${myJvmArgsString} -cp `"${CLASSPATH}`" $CLASS" +} else { + $myArgsString = '"' + $($myArgs -join '" "') + '"' + $COMMAND = "& `"${JAVA}`" ${myJvmArgsString} -cp `"${CLASSPATH}`" $CLASS ${myArgsString}" +} + +if ( $debug -or $help ) { + Write-Error -Message "Shell running: ${COMMAND}" +} + +Invoke-Expression -Command ${COMMAND} + diff --git a/utils/getdown/bin/update.sh b/utils/getdown/bin/update.sh new file mode 100755 index 0000000..92c28c2 --- /dev/null +++ b/utils/getdown/bin/update.sh @@ -0,0 +1,232 @@ +#!/usr/bin/env bash + +declare -a ARGS=("${@}") + +# this whole next part is because there's no readlink -f in Darwin +function readlinkf() { + FINDFILE="$1" + FILE="${FINDFILE}" + PREVFILE="" + C=0 + MAX=100 # just in case we end up in a loop + FOUND=0 + while [ "${C}" -lt "${MAX}" -a "${FILE}" != "${PREVFILE}" -a "${FOUND}" -ne 1 ]; do + PREVFILE="${FILE}" + FILE="$(readlink "${FILE}")" + if [ -z "${FILE}" ]; then + # the readlink is empty means we've arrived at the script, let's canonicalize with pwd + FILE="$(cd "$(dirname "${PREVFILE}")" &> /dev/null && pwd -P)"/"$(basename "${PREVFILE}")" + FOUND=1 + elif [ "${FILE#/}" = "${FILE}" ]; then + # FILE is not an absolute path link, we need to add the relative path to the previous dir + FILE="$(dirname "${PREVFILE}")/${FILE}" + fi + C=$((C+1)) + done + if [ "${FOUND}" -ne 1 ]; then + echo "Could not determine path to actual file '$(basename "${FINDFILE}")'" >&2 + exit 1 + fi + echo "${FILE}" +} + +ISMACOS=0 +if [ "$( uname -s )" = "Darwin" ]; then + ISMACOS=1 +fi + +DEBUG=0 +USERSPACE=0 +INSTALLATION=0 +for RAWARG in "${@}"; do + ARG="${RAWARG%%=*}" + case "${ARG}" in + --debug) + DEBUG=1 + ;; + --installation) + INSTALLATION=1 + ;; + --userspace) + USERSPACE=1 + ;; + *) + echo "Unkown option '${ARG}'" >&2 + exit 2 + esac +done + +# args for the JVM +declare -a JVMARGS=() + +# set vars for being inside the macos App Bundle +if [ "${ISMACOS}" = 1 ]; then +# MACOS ONLY + SCRIPT="$(readlinkf "$0")" + DIR="$(dirname "${SCRIPT}")" + APPDIR="${DIR%/bin}" + JAVABIN="${APPDIR}/jre/Contents/Home/bin" + JAVA="${JAVABIN}/java" + # e.g. APPFOLDER=/Applications/Jalview.app + APPFOLDER="${APPDIR%%.app/*}.app" + VMOPTIONS="${APPFOLDER}/Contents/vmoptions.txt" +else +# NOT MACOS + SCRIPT="$(readlink -f "$0")" + DIR="$(dirname "${SCRIPT}")" + APPDIR="${DIR%/bin}" + JAVABIN="${APPDIR}/jre/bin" + JAVA="${JAVABIN}/java" + # e.g. APPFOLDER=/opt/jalview + APPFOLDER="${APPDIR}" + VMOPTIONS="${APPDIR}/jalviewg.vmoptions" +fi + +# headless java arguments +JVMARGS=( "${JVMARGS[@]}" "-Djava.awt.headless=true" ) +if [ "${ISMACOS}" = 1 ]; then + JVMARGS=( "${JVMARGS[@]}" "-Dapple.awt.UIElement=true" ) +fi + +SYSJAVA=java +GETDOWNTXT="${APPDIR}/getdown.txt" +GETDOWNLAUNCHERJAR="${APPDIR}/getdown-launcher.jar" +GETDOWNCOREJAR="${APPDIR}/resource/getdown-core.jar" +CHANNELPROPS="${APPDIR}/channel.props" +NAME="$( grep app_name= "${CHANNELPROPS}" | cut -d= -f2 )" +echo $NAME +US_NAME="${NAME// /_}" + +GDL_CLASSPATH="" +GDC_CLASSPATH="" +# save an array of JAR paths in case we're in WSL (see later) +declare -a GDL_JARPATHS=() +declare -a GDC_JARPATHS=() +declare -a GDL_ARGS=() + +# getdown-launcher classpath +if [ -e "${GETDOWNLAUNCHERJAR}" ]; then + GDL_CLASSPATH="${GETDOWNLAUNCHERJAR}" + GDL_JARPATHS=( "${GDL_JARPATHS[@]}" "${GETDOWNLAUNCHERJAR}" ) +else + echo "Cannot find $( basename "${GETDOWNLAUNCHERJAR}" ) to run update" >&2 + exit 3 +fi + +# getdown-core classpath +if [ -e "${GETDOWNCOREJAR}" ]; then + GDC_CLASSPATH="${GETDOWNCOREJAR}" + GDC_JARPATHS=( "${GDC_JARPATHS[@]}" "${GETDOWNCOREJAR}" ) +else + echo "Cannot find $( basename "${GETDOWNCOREJAR}" ) to run update" >&2 + exit 4 +fi + +# USER space update +if [ "${USERSPACE}" = 1 ]; then + if [ -e "${VMOPTIONS}" ]; then + LINENUM=0 + while IFS= read -r line; do + # remove comments + line=${line%%#*} + # remove trailing whitespace + line="${line%"${line##*[![:space:]]}"}" + LINENUM=$((LINENUM+1)) + + # add settings for user appdir + if [ "${line}" != "${line#-Dsetuserappdirpath=}" ]; then # starts with -Dsetuserappdirpath= + JVMARGS=( "${JVMARGS[@]}" "${line}" ) + fi + if [ "${line}" != "${line#-Dnouserdefaultappdir=}" ]; then # starts with -Dnouserdefaultappdir= + # don't perform user update if user updates are disabled + NOUSERUPDATEVALUE="$(echo "${line#-Dnouserdefaultappdir=}" | tr '[:upper:]' '[:lower:]')" + if [ "${NOUSERUPDATEVALUE}" = "true" ]; then + echo "Cannot perform manual user-space update when user-space updates are disabled." >&2 + echo "See line ${LINENUM} (${line}) in file '${VMOPTIONS}'." >&2 + exit 5 + fi + JVMARGS=( "${JVMARGS[@]}" "${line}" ) + fi + done < "${VMOPTIONS}" + fi + JVMARGS=( "${JVMARGS[@]}" "-Duserdefaultappdir=true" ) + JVMARGS=( "${JVMARGS[@]}" "-Dnouserdefaultappdir=false" ) + # setting the appdir arg[0] to a blank value so appDir is determined by EnvConfig.getUserAppdir() +fi + +# INSTALLATION update +if [ "${INSTALLATION}" = 1 ]; then + JVMARGS=( "${JVMARGS[@]}" "-Duserdefaultappdir=false" ) + JVMARGS=( "${JVMARGS[@]}" "-Dnouserdefaultappdir=true" ) + JVMARGS=( "${JVMARGS[@]}" "-Dlauncher.appdir=${APPDIR}" ) + JVMARGS=( "${JVMARGS[@]}" "-Dappdir=${APPDIR}" ) + # set GDL_ARGS to these two values +fi + +GDL_ARGS=( "" "" ) + +# both USER and INSTALLATION updates +JVMARGS=( "${JVMARGS[@]}" "-Dinstaller.appdir=${APPDIR}" ) +JVMARGS=( "${JVMARGS[@]}" "-Dinstaller.application_folder=${US_NAME}" ) +JVMARGS=( "${JVMARGS[@]}" "-Dlauncher.script=${SCRIPT}" ) +JVMARGS=( "${JVMARGS[@]}" "-Dlauncher.update=true" ) +JVMARGS=( "${JVMARGS[@]}" "-Dchannel.app_name=${NAME}" ) +JVMARGS=( "${JVMARGS[@]}" "-Dappid=jalview" ) + +# IMPORTANT! tell getdown to update jalview withouth launching +JVMARGS=( "${JVMARGS[@]}" "-Dsilent=true" ) + +# add these Just In Case although jalview shouldn't be launched due to -Dsilent=true +GDL_ARGS=( "${GDL_ARGS[@]}" "--headless" "--quit" "--nojavaconsole" "--nosplash" "--nonews" ) + +# WINDOWS ONLY in Cygwin or Windows Subsystem for Linux (WSL) +# change paths for Cygwin or WSL +if [ "${ISMACOS}" != 1 ]; then # older macos doesn't like uname -o, best to avoid + if [ "$(uname -o)" = "Cygwin" ]; then + # CYGWIN + GDL_CLASSPATH=$(cygpath -pw "${GDL_CLASSPATH}") + elif uname -r | grep -i microsoft | grep -i wsl >/dev/null; then + # WSL + GDL_CLASSPATH="" + for JARPATH in "${GDL_JARPATHS[@]}"; do + [ -n "${GDL_CLASSPATH}" ] && GDL_CLASSPATH="${GDL_CLASSPATH};" + GDL_CLASSPATH="${GDL_CLASSPATH}$(wslpath -aw "${JARPATH}")" + done + JAVA="${JAVA}.exe" + SYSJAVA="java.exe" + fi +fi + +# Is there a bundled Java? If not just try one in the PATH (we need .exe in WSL, added above) +if [ \! -e "${JAVA}" ]; then + JAVA=$SYSJAVA + echo "Cannot find bundled ${JAVA}, using system ${SYSJAVA} and hoping for the best!" >&2 +fi + +# This is just needed for display purposes +function quotearray() { + QUOTEDVALS="" + for VAL in "${@}"; do + if [ \! "$QUOTEDVALS" = "" ]; then + QUOTEDVALS="${QUOTEDVALS} " + fi + QUOTEDVALS="${QUOTEDVALS}\"${VAL}\"" + done + echo $QUOTEDVALS +} + +JVMARGSSTR=$(quotearray "${JVMARGS[@]}") +ARGSSTR=$(quotearray "${GDL_ARGS[@]}") + +if [ "${DEBUG}" = 1 ]; then + echo Shell running: \""${JAVA}"\" ${JVMARGSSTR} -cp \""${GDL_CLASSPATH}"\" com.threerings.getdown.launcher.GetdownApp ${ARGSSTR} >&2 +fi + +"${JAVA}" "${JVMARGS[@]}" -cp "${GDL_CLASSPATH}" com.threerings.getdown.launcher.GetdownApp "${GDL_ARGS[@]}" + +# move updated getdown-launcher.jar into place +if [ "${DEBUG}" = 1 ]; then + echo Shell running: \""${JAVA}"\" ${JVMARGSSTR} -cp \""${GDC_CLASSPATH}"\" jalview.bin.GetdownLauncherUpdate >&2 +fi + +"${JAVA}" "${JVMARGS[@]}" -cp "${GDC_CLASSPATH}" jalview.bin.GetdownLauncherUpdate diff --git a/utils/install4j/install4j10_template.install4j b/utils/install4j/install4j10_template.install4j index b8de2b6..6c8fe21 100644 --- a/utils/install4j/install4j10_template.install4j +++ b/utils/install4j/install4j10_template.install4j @@ -45,6 +45,11 @@ + + + + + @@ -66,8 +71,6 @@ - - @@ -606,22 +609,22 @@ return null; context.getBooleanVariable("makeSymbolicLink") - + String javaHome = System.getProperty("java.home"); String appName = ((String)context.getCompilerVariable("JALVIEW_APPLICATION_NAME")) + ".app"; int i = javaHome.indexOf(appName); -String wrapperLink = null; +String MacOSDir = null; if (i > -1) { - wrapperLink = javaHome.substring(0, i) + appName + File.separator + "Contents" + File.separator + "MacOS" + File.separator + ((String)context.getCompilerVariable("WRAPPER_LINK")); + MacOSDir = javaHome.substring(0, i) + appName + File.separator + "Contents" + File.separator + "MacOS"; } -return wrapperLink; +return MacOSDir; - macWrapperLinkLocation + MacOSDir Util.isMacOS() && !context.getBooleanVariable("isAdmin") // Admin on macOS will add path to /etc/paths.d in Create File action @@ -922,7 +925,7 @@ return console.askOkCancel(message, true); || Util.isUnixInstaller() || ( ( Util.isMacOS() && !Util.hasFullAdminRights() ) // Admin on macOS will add path to /etc/paths.d - && context.getVariable("macWrapperLinkLocation") != null + && context.getVariable("MacOSDir") != null ) ) @@ -1080,7 +1083,7 @@ On ${installer:osName}, user updates will be installed under || Util.isUnixInstaller() || ( ( Util.isMacOS() && !Util.hasFullAdminRights() ) // Admin on macOS will add path to /etc/paths.d - && context.getVariable("macWrapperLinkLocation") != null + && context.getVariable("MacOSDir") != null ) ) @@ -1583,11 +1586,51 @@ return context.getBooleanVariable("allowUserDefaultAppdirUpdates") && co context.getBooleanVariable("appendToPathAction") - + + + + + ../Resources/app/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT} + + + + + ${installer:MacOSDir}/${compiler:WRAPPER_LINK} + + + + Util.isMacOS() && +( + context.getBooleanVariable("makeSymbolicLinkAction") + && context.getVariable("unixBinDir") != null + && context.getVariable("MacOSDir") != null +) + + - ${installer:macWrapperLinkLocation} + ../Resources/app/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_UPDATE_SCRIPT} + + + + + ${installer:MacOSDir}/update_${compiler:WRAPPER_LINK} + + + + Util.isMacOS() && +( + context.getBooleanVariable("makeSymbolicLinkAction") + && context.getVariable("unixBinDir") != null + && context.getVariable("MacOSDir") != null +) + + + + + + ${installer:MacOSDir}/${compiler:WRAPPER_LINK} @@ -1600,7 +1643,27 @@ return context.getBooleanVariable("allowUserDefaultAppdirUpdates") && co ( context.getBooleanVariable("makeSymbolicLinkAction") && context.getVariable("unixBinDir") != null - && context.getVariable("macWrapperLinkLocation") != null + && context.getVariable("MacOSDir") != null +) + + + + + + ${installer:MacOSDir}/update_${compiler:WRAPPER_LINK} + + + + + ${installer:unixBinDir}/update_${compiler:WRAPPER_LINK} + + + + Util.isMacOS() && +( + context.getBooleanVariable("makeSymbolicLinkAction") + && context.getVariable("unixBinDir") != null + && context.getVariable("MacOSDir") != null ) @@ -1939,7 +2002,7 @@ return sb.toString(); - + @@ -1956,7 +2019,7 @@ return sb.toString(); Util.isWindows() && !(((String)context.getCompilerVariable("WRAPPER_LINK")+".bat").equals((String)context.getCompilerVariable("BATCH_WRAPPER_SCRIPT"))) - + @@ -1973,6 +2036,40 @@ return sb.toString(); Util.isWindows() && !(((String)context.getCompilerVariable("WRAPPER_LINK")+".ps1").equals((String)context.getCompilerVariable("POWERSHELL_WRAPPER_SCRIPT"))) + + + + + ${compiler:WRAPPER_SCRIPT_BIN_DIR}/update_${compiler:WRAPPER_LINK}.bat + + + + + + ${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BATCH_UPDATE_SCRIPT} + + + + + Util.isWindows() + + + + + + ${compiler:WRAPPER_SCRIPT_BIN_DIR}/update_${compiler:WRAPPER_LINK}.ps1 + + + + + + ${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:POWERSHELL_UPDATE_SCRIPT} + + + + + Util.isWindows() + @@ -2389,7 +2486,7 @@ return console.askYesNo(message, true); ( Util.isLinux() || Util.isUnixInstaller() || ( Util.isMacOS() - && context.getVariable("macWrapperLinkLocation") != null + && context.getVariable("MacOSDir") != null ) ) && context.getVariable("unixBinDir") != null @@ -2686,6 +2783,7 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch. + @@ -2708,6 +2806,7 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch. + -- 1.7.10.2