}
protected static boolean copyApplicationAppDirToUserAppDir(String applicationAppDirName, String userAppDirName) {
- System.out.println("##### About to run copyApplicationAppDirToUserAppDir");
- System.out.println("##### applicationAppDirName='"+applicationAppDirName+"'");
- System.out.println("##### userAppDirName='"+userAppDirName+"'");
if (applicationAppDirName == null || userAppDirName == null) {
log.warning("Null parameter", "applicationAppDirName", applicationAppDirName, "userAppDirName", userAppDirName);
return false;
log.warning("Problem opening application digest files", new File(applicationAppDir, Digest.digestFile(Digest.VERSION)));
return false;
}
- // copy getdown.txt, digest.txt and digest2.txt, getdown-launcher.jar
+ // copy getdown.txt, digest.txt and digest2.txt, getdown-launcher.jar, channel.props
File getdownLauncher = new File(applicationAppDir, "getdown-launcher.jar");
- for (File from: new File[] {configFile, digest2.getFile(), digest.getFile(), getdownLauncher}) {
+ for (File from: new File[] {configFile, digest2.getFile(), digest.getFile(), getdownLauncher, new File(applicationAppDir, "channel.props")}) {
try {
File to = new File(userAppDir, from.getName());
Files.copy(from.toPath(), to.toPath());
} catch (IOException e) {
- log.warning("Couldn't copy config/digest file", from);
+ log.warning("Couldn't copy config/digest/getdown-launcher/channel file", from);
}
}
MessageDigest md = Digest.getMessageDigest(Digest.VERSION);
for (Resource rsc: copyResources) {
- System.out.println("##### resource: "+rsc.toString());
String digestHash = digest2.getDigest(rsc);
String actualHash;
try {
log.warning("Failed digest hash creation for resource", rsc);
continue;
}
- System.out.println("####### digest "+rsc.getPath()+": "+digestHash);
- System.out.println("####### actual "+rsc.getPath()+": "+actualHash);
if (digestHash == null || actualHash == null) {
log.warning("Something went wrong with digest hashes", digestHash, actualHash);
continue;
try {
Files.copy(from.toPath(), to.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
log.info("Copying resource file", from, to);
- System.out.println("##### Copying file '"+from.toString()+" to "+to.toString());
try {
rsc.applyAttrs();
} catch(IOException e2) {
for (String resourcePath : rsrcs) {
try {
list.add(new Resource(resourcePath, null, new File(applicationAppDir, resourcePath), executable? Resource.EXEC : Resource.NORMAL));
- log.info("##### Adding resource to list", resourcePath);
- //System.out.println("##### Adding resource to list"+ resourcePath);
} catch (Exception e) {
log.warning("Invalid resource '" + resourcePath + "'. " + e);
- //System.out.println("##### Invalid resource "+ resourcePath);
}
}
}
import java.io.File;
import java.io.FileInputStream;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.MessageDigest;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import jalview.util.ChannelProperties;
import jalview.util.HttpUtils;
+import jalview.util.LaunchUtils;
import com.threerings.getdown.data.Application;
* configuration source.
*/
public static EnvConfig create (String[] argv, List<Note> notes) {
- System.out.println("##### out Starting EnvConfig.create()");
- System.err.println("##### err Starting EnvConfig.create()");
+ return create(argv, notes, null);
+ }
+
+ public static EnvConfig create (String[] argv, List<Note> notes, Class startClass) {
String appDir = null;
String appDirProv = null;
String appId = null;
String appBase = null;
String appBaseProv = null;
applicationFolder = System.getProperty("installer.application_folder");
- installerAppdir = System.getProperty("installer.appdir");
+ installerAppdir = System.getProperty(APPLICATION_APPDIR_PROPERTY);
+
appName = System.getProperty("channel.app_name");
// start with bootstrap.properties config, if avaialble
// platform user appdir addition
if (StringUtil.isBlank(appDir)) {
appDir = getUserAppdir();
- appDirProv = "user default";
- userAppDir = appDir != null;
+ if (appDir != null) {
+ appDirProv = "user default";
+ userAppDir = true;
+ }
}
-
- if (SysProps.noUpdate() && Boolean.valueOf(System.getProperty("no" + USE_DEFAULT_APPDIR_PROPERTY)) && appDir == null) {
- appDir = System.getProperty(APPLICATION_APPDIR_PROPERTY);
+
+ // forced by system property to not use user default appdir
+ if (SysProps.noUpdate() && Boolean.valueOf(System.getProperty("no" + USER_DEFAULT_APPDIR_PROPERTY))) {
+ appDir = installerAppdir;
+ appDirProv = "no user default";
+ userAppDir = false;
+ } else if (userAppDir && installerAppdir != null) {
+ // we're going to try and use a different appdir, check if newer getdown-launcher.jar found there, and restart using that one
+ final String getdown = "getdown-launcher.jar";
+ File appdirGetdown = new File(appDir, getdown);
+ if (appdirGetdown.exists()) {
+ File installerGetdown = new File(installerAppdir, getdown);
+ try {
+ Resource appdirGetdownResource = new Resource(appdirGetdown.getAbsolutePath(), null, appdirGetdown, Resource.NORMAL);
+ Resource installerGetdownResource = new Resource(installerGetdown.getAbsolutePath(), null, installerGetdown, Resource.NORMAL);
+ MessageDigest md = Digest.getMessageDigest(1);
+ String appdirGetdownDigest = appdirGetdownResource.computeDigest(1, md, null);
+ String installerGetdownDigest = installerGetdownResource.computeDigest(1, md, null);
+ if (!appdirGetdownDigest.equals(installerGetdownDigest)) { // not the same file content
+ // change classpath and restart. A null startClass looks it up from system property "sun.java.command"
+ String javaBin = LaunchUtils.findJavaBin(false);
+ List<String> removeClasspath = new ArrayList<>();
+ removeClasspath.add(installerGetdown.getAbsolutePath());
+ List<String> prependClasspath = new ArrayList<>();
+ prependClasspath.add(appdirGetdown.getAbsolutePath());
+ // ensure the appdir and appid are also added as command line arguments for backwards compatibility (earlier versions of getdown-launcher.jar)
+ List<String> removeArgs = new ArrayList<>();
+ removeArgs.add(argvAppDir);
+ removeArgs.add(argvAppId);
+ List<String> addArgs = new ArrayList<>();
+ addArgs.add(appDir);
+ addArgs.add(appId);
+ String startClassName = startClass == null ? null : startClass.getName();
+ int exitValue = LaunchUtils.startNewJvm(javaBin, null, null, prependClasspath, null, removeClasspath, startClassName, removeArgs, addArgs, Arrays.asList(argv), true, true, false, true, false);
+
+ if (exitValue == 0) {
+ notes.add(Note.info("Relaunching getdown succeeded. Original getdown exiting now."));
+ setRelaunched(true);
+ return null;
+ } else {
+ notes.add(Note.warn("Relaunching getdown did not seem to succeed with exit value " + exitValue + ". Continuing with this getdown process."));
+ }
+ }
+ } catch (IOException e) {
+ notes.add(Note.warn("IOException opening '" + appdirGetdown.getAbsolutePath() + "' and '" + installerGetdown.getAbsolutePath() + "' as Resources. Continuing without restart. " + e.getMessage()));
+ }
+ }
}
int skipArgs = 2;
}
notes.add(Note.info("Using appdir from " + appDirProv + ": " + appDir));
- System.out.println(Note.info("##### Using appdir from " + appDirProv + ": " + appDir));
if (appId != null) notes.add(Note.info("Using appid from " + appIdProv + ": " + appId));
if (appBase != null) {
notes.add(
Note.info("Using appbase from " + appBaseProv + ": " + appBase));
- System.out.println("##### Using appbase from " + appBaseProv + ": " + appBase);
}
// ensure that the appdir refers to a directory that exists
File appDirFile = new File(appDir);
if (!appDirFile.exists()) {
- System.out.println("##### appDir '"+appDir+"' doesn't exist");
// if we have a bootstrap URL then we auto-create the app dir; this enables an
// installer to simply place a getdown.jar file somewhere and create an OS shortcut
// that runs getdown with an appdir and appbase specified, and have getdown create the
// appdir and download the app into it
- System.out.println("##### appBase='"+appBase+"'");
if (!StringUtil.isBlank(appBase)) {
if (appDirFile.mkdirs()) {
notes.add(Note.info("Auto-created app directory '" + appDir + "'"));
notes.add(Note.warn("Unable to auto-create app dir: '" + appDir + "'"));
}
} else if (userAppDir && Boolean.valueOf(System.getProperty(POPULATE_DEFAULT_APPDIR_PROPERTY))) {
- System.out.println("##### Created appDir='"+appDir+"'");
appBase = System.getProperty(APPLICATION_APPDIR_PROPERTY);
Application.copyApplicationAppDirToUserAppDir(System.getProperty(APPLICATION_APPDIR_PROPERTY), appDir);
} else {
- System.out.println("##### Invalid appDir='"+appDir+"' and no appBase set");
notes.add(Note.error("Invalid appdir '" + appDir + "': directory does not exist"));
return null;
}
}
private static final String getUserAppdir() {
- System.out.println("##### Property '" + USE_DEFAULT_APPDIR_PROPERTY + "' is '" + System.getProperty(USE_DEFAULT_APPDIR_PROPERTY) + "'");
- final String noUseDefaultAppDirProperty = "no" + USE_DEFAULT_APPDIR_PROPERTY;
+ final String noUseDefaultAppDirProperty = "no" + USER_DEFAULT_APPDIR_PROPERTY;
if (Boolean.valueOf(System.getProperty(noUseDefaultAppDirProperty))) {
System.err.println("Not using default user appdir because property '" + noUseDefaultAppDirProperty + "' is '" + System.getProperty(noUseDefaultAppDirProperty) + "'");
return null;
}
- if (!Boolean.valueOf(System.getProperty(USE_DEFAULT_APPDIR_PROPERTY))) {
- System.err.println("Not using default user appdir because property '" + USE_DEFAULT_APPDIR_PROPERTY + "' is '" + System.getProperty(USE_DEFAULT_APPDIR_PROPERTY) + "'");
+ if (!Boolean.valueOf(System.getProperty(USER_DEFAULT_APPDIR_PROPERTY))) {
+ System.err.println("Not using default user appdir because property '" + USER_DEFAULT_APPDIR_PROPERTY + "' is '" + System.getProperty(USER_DEFAULT_APPDIR_PROPERTY) + "'");
return null;
}
- String appdirname = installerAppdir == null || installerAppdir.length() == 0 ? ChannelProperties.FALLBACK_APPNAME : installerAppdir;
- String userAppDataPath;
+ String appdirname = applicationFolder == null || applicationFolder.length() == 0 ? ChannelProperties.FALLBACK_APPNAME : applicationFolder;
String home = System.getProperty("user.home");
String appname = StringUtil.isBlank(appName) ? ChannelProperties.FALLBACK_APPNAME : appName;
final String FS = File.separator;
+ String appDataPath;
+ String append;
if (LaunchUtil.isMacOS()) {
- userAppDataPath = home + FS + "Library" + FS + "Application Support" + FS + "Jalview-Desktop" + FS + appname + FS + "app";
+ appDataPath = osAppDataPathMap.get("macos");
+ append = appname;
} else if (LaunchUtil.isWindows()) {
- userAppDataPath = home + FS + "AppData" + FS + "Local" + FS + "Jalview-Desktop" + FS + appdirname + FS + "app";
+ appDataPath = osAppDataPathMap.get("windows");
+ append = appdirname;
} else if (LaunchUtil.isLinux()) {
- userAppDataPath = home + FS + ".local" + FS + "share" + FS + "jalview-desktop" + FS + appdirname.toLowerCase(Locale.ROOT) + FS + "app";
+ appDataPath = osAppDataPathMap.get("linux");
+ append = appdirname.toLowerCase(Locale.ROOT);
} else {
- userAppDataPath = home + FS + ".jalview-desktop" + FS + appdirname.toLowerCase(Locale.ROOT) + FS + "app";
+ appDataPath = osAppDataPathMap.get("other");
+ append = appdirname.toLowerCase(Locale.ROOT);
+ }
+ if (!"/".equals(FS)) {
+ appDataPath = appDataPath.replaceAll("/", FS);
}
- System.out.println("##### About to return userAppDataPath value '"+userAppDataPath+"'");
- return userAppDataPath;
+ String returnString = home + FS + appDataPath + FS + append + FS + "app";
+ return returnString;
+ }
+
+ public static void setRelaunched(boolean b) {
+ relaunched = b;
+ }
+
+ public static boolean getRelaunched() {
+ return relaunched;
}
+ private static boolean relaunched = false;
+
private static final String USER_HOME_KEY = "${user.home}";
private static String applicationFolder = null;
private static String appName = null;
- private static final String USE_DEFAULT_APPDIR_PROPERTY = "usedefaultappdir";
+ private static final String USER_DEFAULT_APPDIR_PROPERTY = "userdefaultappdir";
private static final String APPLICATION_APPDIR_PROPERTY = "installer.appdir";
private static final String POPULATE_DEFAULT_APPDIR_PROPERTY= "populatedefaultappdir";
+
+ private static final Map<String,String> osAppDataPathMap;
+
+ static {
+ // paths from user.home with application folder added to end. '/' replaced with file.separator
+ osAppDataPathMap = new HashMap<>();
+ osAppDataPathMap.put("macos", "Library/Application Support/Jaview-Desktop");
+ osAppDataPathMap.put("linux", ".local/share/jalview-desktop");
+ osAppDataPathMap.put("windows", "AppData/Local/Jalview-Desktop");
+ osAppDataPathMap.put("other", ".jalview-desktop");
+ }
}
}
// first look in our application directory for an installed VM
- final String appDir = isMacOS() ?
+ final String appJreDir = isMacOS() ?
(new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath()) + "/Contents/Home"
: new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath();
- String javaBin = LaunchUtils.findJavaBin(appDir, windebug, false);
+ String javaBin = LaunchUtils.findJavaBin(appJreDir, windebug, true, false);
// then fall back to the VM in which we're already running
if (javaBin == null) {
- javaBin = LaunchUtils.findJavaBin(System.getProperty("java.home"), windebug, false);
+ javaBin = LaunchUtils.findJavaBin(System.getProperty("java.home"), windebug, true, false);
}
// then throw up our hands and hope for the best
if (javaBin == null) {
- javaBin = LaunchUtils.findJavaBin(null, windebug, true);
+ javaBin = LaunchUtils.findJavaBin(null, windebug, false, true);
log.warning("Unable to find java [appdir=" + appdir +
", java.home=" + System.getProperty("java.home") + "]!");
}
+++ /dev/null
-package jalview.bin;
-
-public class Console {
- public static boolean initLogger() {
- return false;
- }
- public static void outPrintln(String s) {
- }
- public static void errPrintln(String s) {
- }
-}
package jalview.util;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
public class ErrorLog
{
private static boolean hasConsole = true;
+ private static Class console = null;
+
+ private static Method initLogger = null;
+
+ private static Method errPrintln = null;
+
+ private static Method outPrintln = null;
+
+ private static String prefix = null;
+
+ public static void setHasConsole(boolean b)
+ {
+ hasConsole = b;
+ }
+
+ public static void setPrefix(String s)
+ {
+ prefix = s;
+ }
+
public static void outPrintln(String message)
{
println(message, false);
public static void println(String message, boolean err)
{
- if (hasConsole)
+ println(message, err, true);
+ }
+
+ public static void println(String message0, boolean err,
+ boolean thisHasConsole)
+ {
+ String message = prefix == null ? message0 : prefix + message0;
+ if (thisHasConsole && hasConsole)
{
try
{
- hasConsole = jalview.bin.Console.initLogger();
- if (hasConsole)
+ if (console == null)
+ {
+ Class console = Class.forName("jalview.bin.Console");
+ }
+ if (console == null)
+ {
+ hasConsole = false;
+ }
+ else
{
- if (err)
+ if (initLogger == null && console != null)
{
- jalview.bin.Console.errPrintln(message);
+ initLogger = console.getMethod("initLogger");
}
- else
+ hasConsole = console == null || initLogger == null
+ || (Boolean) initLogger.invoke(null);
+ if (hasConsole && console != null)
{
- jalview.bin.Console.outPrintln(message);
+ if (err)
+ {
+ if (errPrintln == null)
+ {
+ errPrintln = console.getMethod("errPrintln", String.class);
+ }
+ errPrintln.invoke(null, message);
+ }
+ else
+ {
+ if (outPrintln == null)
+ {
+ outPrintln = console.getMethod("outPrintln", String.class);
+ }
+ outPrintln.invoke(null, message);
+ }
}
}
+ } catch (ClassNotFoundException | NoSuchMethodException e)
+ {
+ hasConsole = false;
+ System.err.println(
+ "jalview.util.ErrorLog has no jalview.bin.Console.initLogger(). Using System.err and System.out.");
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException e)
+ {
+ hasConsole = false;
+ System.err.println(
+ "jalview.util.ErrorLog had a problem calling a method of jalview.bin.Console. Using System.err and System.out.");
} catch (Exception e)
{
e.printStackTrace();
"jalview.util.ErrorLog has no jalview.bin.Console. Using System.err and System.out.");
}
}
- if (!hasConsole)
+ if (!(thisHasConsole && hasConsole))
{
if (err)
{
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
+import java.net.URISyntaxException;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
public class LaunchUtils
{
null);
if (JCV == null)
{
- ErrorLog.errPrintln("Could not obtain JAVA_COMPILE_VERSION for comparison");
+ ErrorLog.errPrintln(
+ "Could not obtain JAVA_COMPILE_VERSION for comparison");
return -2;
}
JAVA_COMPILE_VERSION = Integer.parseInt(JCV);
return JAVA_VERSION;
}
+ public static String getJarPath(Class c)
+ {
+ try
+ {
+ return c.getProtectionDomain().getCodeSource().getLocation().toURI()
+ .getPath();
+ } catch (URISyntaxException e)
+ {
+ ErrorLog.errPrintln("Problem with class source location");
+ return null;
+ }
+ }
+
public static boolean checkJavaVersion()
{
if (LaunchUtils.isJS)
public static String findJavaBin(boolean winConsole)
{
- return findJavaBin(System.getProperty("java.home"), winConsole, true);
+ return findJavaBin(System.getProperty("java.home"), winConsole, true,
+ true);
+ }
+
+ public static String findJavaBin(boolean winConsole,
+ boolean applicationName, boolean generic)
+ {
+ return findJavaBin(System.getProperty("java.home"), winConsole,
+ applicationName, generic);
}
/*
* Returns a string path to the most likely java binary wanted to run this
* installation of Jalview.
*
+ * @param javaHome Try this javaHome dir (defaults to the running java.home).
* @param winConsole whether to use java.exe (console) in preference to javaw.exe
* (only affects Windows).
- * @param javaHome Try this javaHome dir (defaults to the running java.home).
+ * @param applicationName Look to see if the Jalview application name symbolic link is present and use it.
* @param generic Return a generic java command if not found.
*/
public static String findJavaBin(String javaHome, boolean winConsole,
- boolean generic)
+ boolean applicationName, boolean generic)
{
String javaBin = null;
final String javaExe = winConsole ? "java.exe" : "javaw.exe";
if (javaHome != null)
{
+ String propertyAppName = null;
+ String appName = null;
// property "channel.app_name" is set by install4j when launching getdown
- String propertyAppName = System.getProperty("channel.app_name");
- final String appName = (propertyAppName != null
- && propertyAppName.length() > 0) ? propertyAppName
- : ChannelProperties.getProperty("app_name");
+ if (applicationName)
+ {
+ propertyAppName = System.getProperty("channel.app_name");
+ appName = (propertyAppName != null && propertyAppName.length() > 0)
+ ? propertyAppName
+ : ChannelProperties.getProperty("app_name");
+ }
final String javaBinDir = javaHome + File.separator + "bin"
+ File.separator;
// appName and "Jalview" will not point to javaw.exe or java.exe but in
// this case that's okay because the taskbar display name problem doesn't
// manifest in Windows. See JAL-3820, JAL-4189.
- for (String name : new String[] { appName, ChannelProperties.FALLBACK_APPNAME, java, javaExe })
+ List<String> potentialJavaBin = new ArrayList<>();
+ if (applicationName)
{
+ if (appName != null)
+ {
+ potentialJavaBin.add(appName);
+ }
+ if (ChannelProperties.FALLBACK_APPNAME != null)
+ {
+ potentialJavaBin.add(ChannelProperties.FALLBACK_APPNAME);
+ }
+ }
+ potentialJavaBin.add(java);
+ potentialJavaBin.add(javaExe);
+ for (String name : potentialJavaBin)
+ {
+ if (name == null)
+ {
+ continue;
+ }
if (LaunchUtils.checkJVMSymlink(javaBinDir + name, winConsole))
{
javaBin = javaBinDir + name;
}
return false;
}
+
+ /**
+ * Create a java command that matches the currently running java process and
+ * optionally remove/add some JVM and application parameters.
+ *
+ * @param String
+ * javaBinary The java binary to use. null uses the same as current
+ * process.
+ * @param String[]
+ * removeJvmArguments The (start of) JVM arguments to remove.
+ * @param String[]
+ * addJvmArguments JVM arguments to add.
+ * @param String[]
+ * prependToClasspath Add these dirs to the start of the classpath
+ * @param String[]
+ * appendToClasspath Add these dirs to the end of the classpath
+ * @param String[]
+ * deleteFromClasspath Remove these dirs from the existing classpath
+ * @param String
+ * startClass The name of the start class if different. null if the
+ * same.
+ * @param String[]
+ * removeAppArguments The (start of) application arguments to remove.
+ * @param String[]
+ * addAppArguments Application arguments to add.
+ * @param boolean
+ * terminate Flag to terminate this process after starting new
+ * process.
+ */
+ public static int startNewJvm(String javaBinary,
+ List<String> removeJvmArguments, List<String> addJvmArguments,
+ List<String> prependToClasspath, List<String> appendToClasspath,
+ List<String> removeFromClasspath, String startClass,
+ List<String> removeAppArguments, List<String> addAppArguments,
+ List<String> appArguments, boolean launcherprint,
+ boolean launcherwait, boolean launcherstop, boolean debug,
+ boolean quiet)
+ {
+ int exitValue = -1;
+ if (javaBinary == null)
+ {
+ javaBinary = findJavaBin(false, true, true);
+ }
+
+ List<String> classpathDirs = new ArrayList<>();
+ if (prependToClasspath != null)
+ {
+ classpathDirs.addAll(prependToClasspath);
+ }
+
+ String classpath = ManagementFactory.getRuntimeMXBean().getClassPath();
+ if (removeFromClasspath != null)
+ {
+ Set<String> removeCp = new HashSet<>();
+ for (String dcp : removeFromClasspath)
+ {
+ try
+ {
+ String canPath = new File(dcp).getCanonicalPath();
+ removeCp.add(canPath);
+ } catch (IOException e)
+ {
+ ErrorLog.errPrintln(
+ "Problem getting canonical path. " + e.getMessage());
+ }
+ }
+ for (String cp : classpath.split(File.pathSeparator))
+ {
+ try
+ {
+ String canPath = new File(cp).getCanonicalPath();
+ if (!removeCp.contains(canPath))
+ {
+ classpathDirs.add(cp);
+ }
+ } catch (IOException e)
+ {
+ ErrorLog.errPrintln(
+ "Problem getting canonical path. " + e.getMessage());
+ }
+ }
+ }
+ else
+ {
+ classpathDirs
+ .addAll(Arrays.asList(classpath.split(File.pathSeparator)));
+ }
+ if (appendToClasspath != null)
+ {
+ classpathDirs.addAll(appendToClasspath);
+ }
+
+ List<String> jvmArguments = new ArrayList<>();
+ List<String> originalJvmArguments = ManagementFactory.getRuntimeMXBean()
+ .getInputArguments();
+ if (removeJvmArguments != null)
+ {
+ for (String jvmArg : originalJvmArguments)
+ {
+ boolean addArg = true;
+ for (String rmArg : removeJvmArguments)
+ {
+ if (jvmArg.startsWith(rmArg))
+ {
+ addArg = false;
+ break;
+ }
+ }
+ if (addArg)
+ {
+ jvmArguments.add(jvmArg);
+ }
+ }
+ }
+ else
+ {
+ jvmArguments.addAll(originalJvmArguments);
+ }
+ if (addJvmArguments != null)
+ {
+ jvmArguments.addAll(addJvmArguments);
+ }
+
+ if (startClass == null)
+ {
+ // this isn't always reliable
+ startClass = System.getProperty("sun.java.command");
+ }
+
+ List<String> applicationArguments = new ArrayList<>();
+ if (removeAppArguments != null)
+ {
+ Set<String> removeArgs = new HashSet<>(removeAppArguments);
+ for (String appArg : appArguments)
+ {
+ if (!removeArgs.contains(removeArgs))
+ {
+ applicationArguments.add(appArg);
+ }
+ }
+ }
+ else
+ {
+ applicationArguments.addAll(appArguments);
+ }
+ if (addAppArguments != null)
+ {
+ applicationArguments.addAll(addAppArguments);
+ }
+
+ List<String> command = new ArrayList<>();
+ // java command
+ command.add(javaBinary);
+
+ // classpath
+ command.add("-cp");
+ command.add(String.join(File.pathSeparator, classpathDirs));
+
+ // jvm args
+ command.addAll(jvmArguments);
+
+ // start class
+ command.add(startClass);
+
+ // application args
+ command.addAll(applicationArguments);
+
+ final ProcessBuilder builder = new ProcessBuilder(command);
+
+ if (Boolean.parseBoolean(System.getProperty("launcherprint", "false"))
+ || launcherprint)
+ {
+ syserr(debug, quiet,
+ "COMMAND: " + String.join(" ", builder.command()));
+ }
+
+ if (Boolean.parseBoolean(System.getProperty("launcherstop", "false"))
+ || (debug && launcherstop))
+ {
+ syserr(debug, quiet,
+ "System property 'launcherstop' is set and not 'false'. Exiting.");
+ System.exit(0);
+ }
+ try
+ {
+ builder.inheritIO();
+ Process process = builder.start();
+ if (launcherwait)
+ {
+ syserr(debug, quiet, "Launching application process");
+ exitValue = process.waitFor();
+ syserr(debug, quiet,
+ "Application process return with value " + exitValue);
+ }
+ else
+ {
+ int waitInt = 0;
+ syserr(debug, quiet,
+ "Wait time for application process is " + waitInt + "ms");
+ if (process.waitFor(waitInt, TimeUnit.MILLISECONDS))
+ {
+ exitValue = process.exitValue();
+ }
+ else
+ {
+ exitValue = -2;
+ }
+ }
+ syserr(debug, quiet, "Launcher process ending");
+ } catch (IOException e)
+ {
+ if (e.getMessage().toLowerCase(Locale.ROOT).contains("memory"))
+ {
+ syserr(true, quiet, "Caught a memory exception: " + e.getMessage());
+ // Probably the "Cannot allocate memory" error, try without the memory
+ // setting
+ ArrayList<String> commandNoMem = new ArrayList<>();
+ for (int i = 0; i < command.size(); i++)
+ {
+ if (!command.get(i).startsWith("-Xmx"))
+ {
+ commandNoMem.add(command.get(i));
+ }
+ }
+ final ProcessBuilder builderNoMem = new ProcessBuilder(
+ commandNoMem);
+ syserr(true, quiet, "Command without memory setting: "
+ + String.join(" ", builderNoMem.command()));
+ try
+ {
+ builderNoMem.inheritIO();
+ Process processNoMem = builderNoMem.start();
+ exitValue = processNoMem.waitFor();
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ else
+ {
+ e.printStackTrace();
+ }
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return exitValue;
+ }
+
+ public static void syserr(boolean debug, boolean quiet, String message)
+ {
+ if (debug && !quiet)
+ {
+ ErrorLog.errPrintln("DEBUG - " + message);
+ }
+ }
}
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
+ out.println(line);
+ out.flush();
// check for desktop creation line and end early
if (!_disposed && line.endsWith("JALVIEW: CREATED DESKTOP")) {
// pump the percent up to 100%
// let nature take its course
}
}
- out.println(line);
- out.flush();
}
} catch (IOException ioe) {
log.warning("Failure copying", "in", in, "out", out, "error", ioe);
public class GetdownApp
{
public static List<String> startupFilesParameters = new ArrayList<>();
+
/**
* The main entry point of the Getdown launcher application.
*/
* @throws Exception if anything goes wrong starting Getdown.
*/
public static Getdown start (String[] argv) throws Exception {
+ jalview.util.ErrorLog.setHasConsole(false);
+ jalview.util.ErrorLog.setPrefix("GETDOWN - ");
List<EnvConfig.Note> notes = new ArrayList<>();
- EnvConfig envc = EnvConfig.create(argv, notes);
+ EnvConfig envc = EnvConfig.create(argv, notes, GetdownApp.class);
if (envc == null) {
- if (!notes.isEmpty()) for (EnvConfig.Note n : notes) System.err.println(n.message);
- else System.err.println("Usage: java -jar getdown.jar [app_dir] [app_id] [app args]");
- System.exit(-1);
+ if (!notes.isEmpty()) {
+ for (EnvConfig.Note n : notes) {
+ System.err.println(n.message);
+ }
+ } else {
+ System.err.println("Usage: java -jar getdown.jar [app_dir] [app_id] [app args]");
+ }
+ System.exit(EnvConfig.getRelaunched() ? 0 : -1);
}
// pipe our output into a file in the application directory
echo "Setting VERSION to '$VERSION'"
perl -p -i -e 's|(<version>)[^<]*JVL[^<]*(</version>)|${1}$ENV{VERSION}${2}|;' pom.xml */pom.xml
+
+echo "Making sure jalview classes are up-to-date"
+for x in $(find core/src/main/java/jalview launcher/src/main/java/jalview -name "*.java")
+do
+ y=${x##*java/}
+ if [ -e "../../../src/${y}" ]; then
+ echo /bin/cp "../../../src/${y}" "${x}"
+ /bin/cp "../../../src/${y}" "${x}"
+ else
+ echo "'../../../src/${y}' doesn't exist, not copying"
+ fi
+done
mvn package -Dgetdown.host.whitelist="jalview.org,*.jalview.org" -Dallow_file_protocol=false -Dconnect_timeout=8 -Dread_timeout=15
RET=$?
if [ x$RET = x0 ]; then
package jalview.bin;
import java.io.File;
-import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.TimeUnit;
import jalview.bin.argparser.Arg;
import jalview.util.ChannelProperties;
+import jalview.util.ErrorLog;
import jalview.util.LaunchUtils;
/**
+ LaunchUtils.getJavaCompileVersion() + ".");
}
+ ErrorLog.setPrefix("LAUNCHER - ");
+
String jvmmempc = null;
String jvmmemmax = null;
boolean debug = false;
// if we're using jalview.bin.Launcher we always assume a console is in use
final String javaBin = LaunchUtils.findJavaBin(true);
- List<String> command = new ArrayList<>();
- command.add(javaBin);
+ List<String> removeJvmArgs = new ArrayList<>();
+ List<String> addJvmArgs = new ArrayList<>();
+ // command.add(javaBin);
String memSetting = null;
- for (String jvmArg : ManagementFactory.getRuntimeMXBean()
- .getInputArguments())
- {
- command.add(jvmArg);
- }
- command.add("-cp");
- command.add(ManagementFactory.getRuntimeMXBean().getClassPath());
+ List<String> jvmArgs = ManagementFactory.getRuntimeMXBean()
+ .getInputArguments();
// use saved preferences if no cmdline args
boolean useCustomisedSettings = LaunchUtils
boolean dockName = false;
boolean headlessProp = false;
boolean macosHeadlessProp = false;
- for (int i = 0; i < command.size(); i++)
+ for (int i = 0; i < jvmArgs.size(); i++)
{
- String arg = command.get(i);
+ String arg = jvmArgs.get(i);
if (arg.startsWith("-Xmx"))
{
// only use -Xmx if jvmmemmax and jvmmempc have not been set
{
memSetting = "-Xmx" + Long.toString(maxMemLong);
memSet = true;
- command.add(memSetting);
+ addJvmArgs.add(memSetting);
+ removeJvmArgs.add("-Xmx");
}
}
{
String dockIconPath = System.getProperty("getdownappdir", ".")
+ File.separator + "resource/jalview_logo.png";
- command.add("-Xdock:icon=" + dockIconPath);
+ addJvmArgs.add("-Xdock:icon=" + dockIconPath);
}
if (!dockName)
{
// -Xdock:name=... doesn't actually work :(
// Leaving it in in case it gets fixed
- command.add("-Xdock:name=" + appName);
+ addJvmArgs.add("-Xdock:name=" + appName);
// This also does not work for the dock
- command.add("-Dcom.apple.mrj.application.apple.menu.about.name="
+ addJvmArgs.add("-Dcom.apple.mrj.application.apple.menu.about.name="
+ appName);
}
}
/* not setting this in java invocation of running jalview due to problem with Jmol */
if (help)
{
- command.add("-D" + headlessProperty + "=true");
+ addJvmArgs.add("-D" + headlessProperty + "=true");
}
}
if (headless && LaunchUtils.isMac && !macosHeadlessProp)
{
System.setProperty(macosHeadlessProperty, "true");
- command.add("-D" + macosHeadlessProperty + "=true");
+ addJvmArgs.add("-D" + macosHeadlessProperty + "=true");
}
String scalePropertyArg = HiDPISetting.getScalePropertyArg();
if (scalePropertyArg != null)
{
- syserr(debug, quiet, "Running " + startClass + " with scale setting "
- + scalePropertyArg);
- command.add(scalePropertyArg);
+ LaunchUtils.syserr(debug, quiet, "Running " + startClass
+ + " with scale setting " + scalePropertyArg);
+ addJvmArgs.add(scalePropertyArg);
}
- command.add(startClass);
- command.addAll(arguments);
+ int exitValue = LaunchUtils.startNewJvm(javaBin, removeJvmArgs,
+ addJvmArgs, null, null, null, startClass, null, null, arguments,
+ launcherprint, launcherwait, launcherstop, debug, quiet);
- final ProcessBuilder builder = new ProcessBuilder(command);
-
- if ((Boolean.parseBoolean(System.getProperty("launcherprint", "false"))
- || launcherprint))
- {
- syserr(debug, quiet,
- "LAUNCHER COMMAND: " + String.join(" ", builder.command()));
- }
- syserr(debug, quiet,
- "Running " + startClass + " with "
- + (memSetting == null ? "no memory setting"
- : ("memory setting " + memSetting)));
-
- if (Boolean.parseBoolean(System.getProperty("launcherstop", "false"))
- || (debug && launcherstop))
- {
- syserr(debug, quiet,
- "System property 'launcherstop' is set and not 'false'. Exiting.");
- System.exit(0);
- }
- try
- {
- builder.inheritIO();
- Process process = builder.start();
- if (wait || launcherwait)
- {
- syserr(debug, quiet, "Launching application process");
- process.waitFor();
- }
- else
- {
- int waitInt = 0;
- syserr(debug, quiet,
- "Wait time for application process is " + waitInt + "ms");
- process.waitFor(waitInt, TimeUnit.MILLISECONDS);
- }
- syserr(debug, quiet, "Launcher process ending");
- } catch (IOException e)
- {
- if (e.getMessage().toLowerCase(Locale.ROOT).contains("memory"))
- {
- jalview.bin.Console
- .errPrintln("Caught a memory exception: " + e.getMessage());
- // Probably the "Cannot allocate memory" error, try without the memory
- // setting
- ArrayList<String> commandNoMem = new ArrayList<>();
- for (int i = 0; i < command.size(); i++)
- {
- if (!command.get(i).startsWith("-Xmx"))
- {
- commandNoMem.add(command.get(i));
- }
- }
- final ProcessBuilder builderNoMem = new ProcessBuilder(
- commandNoMem);
- jalview.bin.Console.errPrintln("Command without memory setting: "
- + String.join(" ", builderNoMem.command()));
- try
- {
- builderNoMem.inheritIO();
- Process processNoMem = builderNoMem.start();
- processNoMem.waitFor();
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- else
- {
- e.printStackTrace();
- }
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- private static void syserr(boolean debug, boolean quiet, String message)
- {
- if (debug && !quiet)
- {
- jalview.bin.Console.errPrintln("LAUNCHERDEBUG - " + message);
- }
+ LaunchUtils.syserr(debug, quiet, "JVM exited with value " + exitValue);
}
}
package jalview.util;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
public class ErrorLog
{
private static boolean hasConsole = true;
+ private static Class console = null;
+
+ private static Method initLogger = null;
+
+ private static Method errPrintln = null;
+
+ private static Method outPrintln = null;
+
+ private static String prefix = null;
+
+ public static void setHasConsole(boolean b)
+ {
+ hasConsole = b;
+ }
+
+ public static void setPrefix(String s)
+ {
+ prefix = s;
+ }
+
public static void outPrintln(String message)
{
println(message, false);
public static void println(String message, boolean err)
{
- if (hasConsole)
+ println(message, err, true);
+ }
+
+ public static void println(String message0, boolean err,
+ boolean thisHasConsole)
+ {
+ String message = prefix == null ? message0 : prefix + message0;
+ if (thisHasConsole && hasConsole)
{
try
{
- hasConsole = jalview.bin.Console.initLogger();
- if (hasConsole)
+ if (console == null)
+ {
+ Class console = Class.forName("jalview.bin.Console");
+ }
+ if (console == null)
+ {
+ hasConsole = false;
+ }
+ else
{
- if (err)
+ if (initLogger == null && console != null)
{
- jalview.bin.Console.errPrintln(message);
+ initLogger = console.getMethod("initLogger");
}
- else
+ hasConsole = console == null || initLogger == null
+ || (Boolean) initLogger.invoke(null);
+ if (hasConsole && console != null)
{
- jalview.bin.Console.outPrintln(message);
+ if (err)
+ {
+ if (errPrintln == null)
+ {
+ errPrintln = console.getMethod("errPrintln", String.class);
+ }
+ errPrintln.invoke(null, message);
+ }
+ else
+ {
+ if (outPrintln == null)
+ {
+ outPrintln = console.getMethod("outPrintln", String.class);
+ }
+ outPrintln.invoke(null, message);
+ }
}
}
+ } catch (ClassNotFoundException | NoSuchMethodException e)
+ {
+ hasConsole = false;
+ System.err.println(
+ "jalview.util.ErrorLog has no jalview.bin.Console.initLogger(). Using System.err and System.out.");
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException e)
+ {
+ hasConsole = false;
+ System.err.println(
+ "jalview.util.ErrorLog had a problem calling a method of jalview.bin.Console. Using System.err and System.out.");
} catch (Exception e)
{
e.printStackTrace();
"jalview.util.ErrorLog has no jalview.bin.Console. Using System.err and System.out.");
}
}
- if (!hasConsole)
+ if (!(thisHasConsole && hasConsole))
{
if (err)
{
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
+import java.net.URISyntaxException;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
public class LaunchUtils
{
null);
if (JCV == null)
{
- ErrorLog.errPrintln("Could not obtain JAVA_COMPILE_VERSION for comparison");
+ ErrorLog.errPrintln(
+ "Could not obtain JAVA_COMPILE_VERSION for comparison");
return -2;
}
JAVA_COMPILE_VERSION = Integer.parseInt(JCV);
return JAVA_VERSION;
}
+ public static String getJarPath(Class c)
+ {
+ try
+ {
+ return c.getProtectionDomain().getCodeSource().getLocation().toURI()
+ .getPath();
+ } catch (URISyntaxException e)
+ {
+ ErrorLog.errPrintln("Problem with class source location");
+ return null;
+ }
+ }
+
public static boolean checkJavaVersion()
{
if (LaunchUtils.isJS)
public static String findJavaBin(boolean winConsole)
{
- return findJavaBin(System.getProperty("java.home"), winConsole, true);
+ return findJavaBin(System.getProperty("java.home"), winConsole, true,
+ true);
+ }
+
+ public static String findJavaBin(boolean winConsole,
+ boolean applicationName, boolean generic)
+ {
+ return findJavaBin(System.getProperty("java.home"), winConsole,
+ applicationName, generic);
}
/*
* Returns a string path to the most likely java binary wanted to run this
* installation of Jalview.
*
+ * @param javaHome Try this javaHome dir (defaults to the running java.home).
* @param winConsole whether to use java.exe (console) in preference to javaw.exe
* (only affects Windows).
- * @param javaHome Try this javaHome dir (defaults to the running java.home).
+ * @param applicationName Look to see if the Jalview application name symbolic link is present and use it.
* @param generic Return a generic java command if not found.
*/
public static String findJavaBin(String javaHome, boolean winConsole,
- boolean generic)
+ boolean applicationName, boolean generic)
{
String javaBin = null;
final String javaExe = winConsole ? "java.exe" : "javaw.exe";
if (javaHome != null)
{
+ String propertyAppName = null;
+ String appName = null;
// property "channel.app_name" is set by install4j when launching getdown
- String propertyAppName = System.getProperty("channel.app_name");
- final String appName = (propertyAppName != null
- && propertyAppName.length() > 0) ? propertyAppName
- : ChannelProperties.getProperty("app_name");
+ if (applicationName)
+ {
+ propertyAppName = System.getProperty("channel.app_name");
+ appName = (propertyAppName != null && propertyAppName.length() > 0)
+ ? propertyAppName
+ : ChannelProperties.getProperty("app_name");
+ }
final String javaBinDir = javaHome + File.separator + "bin"
+ File.separator;
// appName and "Jalview" will not point to javaw.exe or java.exe but in
// this case that's okay because the taskbar display name problem doesn't
// manifest in Windows. See JAL-3820, JAL-4189.
- for (String name : new String[] { appName, ChannelProperties.FALLBACK_APPNAME, java, javaExe })
+ List<String> potentialJavaBin = new ArrayList<>();
+ if (applicationName)
{
+ if (appName != null)
+ {
+ potentialJavaBin.add(appName);
+ }
+ if (ChannelProperties.FALLBACK_APPNAME != null)
+ {
+ potentialJavaBin.add(ChannelProperties.FALLBACK_APPNAME);
+ }
+ }
+ potentialJavaBin.add(java);
+ potentialJavaBin.add(javaExe);
+ for (String name : potentialJavaBin)
+ {
+ if (name == null)
+ {
+ continue;
+ }
if (LaunchUtils.checkJVMSymlink(javaBinDir + name, winConsole))
{
javaBin = javaBinDir + name;
}
return false;
}
+
+ /**
+ * Create a java command that matches the currently running java process and
+ * optionally remove/add some JVM and application parameters.
+ *
+ * @param String
+ * javaBinary The java binary to use. null uses the same as current
+ * process.
+ * @param String[]
+ * removeJvmArguments The (start of) JVM arguments to remove.
+ * @param String[]
+ * addJvmArguments JVM arguments to add.
+ * @param String[]
+ * prependToClasspath Add these dirs to the start of the classpath
+ * @param String[]
+ * appendToClasspath Add these dirs to the end of the classpath
+ * @param String[]
+ * deleteFromClasspath Remove these dirs from the existing classpath
+ * @param String
+ * startClass The name of the start class if different. null if the
+ * same.
+ * @param String[]
+ * removeAppArguments The (start of) application arguments to remove.
+ * @param String[]
+ * addAppArguments Application arguments to add.
+ * @param boolean
+ * terminate Flag to terminate this process after starting new
+ * process.
+ */
+ public static int startNewJvm(String javaBinary,
+ List<String> removeJvmArguments, List<String> addJvmArguments,
+ List<String> prependToClasspath, List<String> appendToClasspath,
+ List<String> removeFromClasspath, String startClass,
+ List<String> removeAppArguments, List<String> addAppArguments,
+ List<String> appArguments, boolean launcherprint,
+ boolean launcherwait, boolean launcherstop, boolean debug,
+ boolean quiet)
+ {
+ int exitValue = -1;
+ if (javaBinary == null)
+ {
+ javaBinary = findJavaBin(false, true, true);
+ }
+
+ List<String> classpathDirs = new ArrayList<>();
+ if (prependToClasspath != null)
+ {
+ classpathDirs.addAll(prependToClasspath);
+ }
+
+ String classpath = ManagementFactory.getRuntimeMXBean().getClassPath();
+ if (removeFromClasspath != null)
+ {
+ Set<String> removeCp = new HashSet<>();
+ for (String dcp : removeFromClasspath)
+ {
+ try
+ {
+ String canPath = new File(dcp).getCanonicalPath();
+ removeCp.add(canPath);
+ } catch (IOException e)
+ {
+ ErrorLog.errPrintln(
+ "Problem getting canonical path. " + e.getMessage());
+ }
+ }
+ for (String cp : classpath.split(File.pathSeparator))
+ {
+ try
+ {
+ String canPath = new File(cp).getCanonicalPath();
+ if (!removeCp.contains(canPath))
+ {
+ classpathDirs.add(cp);
+ }
+ } catch (IOException e)
+ {
+ ErrorLog.errPrintln(
+ "Problem getting canonical path. " + e.getMessage());
+ }
+ }
+ }
+ else
+ {
+ classpathDirs
+ .addAll(Arrays.asList(classpath.split(File.pathSeparator)));
+ }
+ if (appendToClasspath != null)
+ {
+ classpathDirs.addAll(appendToClasspath);
+ }
+
+ List<String> jvmArguments = new ArrayList<>();
+ List<String> originalJvmArguments = ManagementFactory.getRuntimeMXBean()
+ .getInputArguments();
+ if (removeJvmArguments != null)
+ {
+ for (String jvmArg : originalJvmArguments)
+ {
+ boolean addArg = true;
+ for (String rmArg : removeJvmArguments)
+ {
+ if (jvmArg.startsWith(rmArg))
+ {
+ addArg = false;
+ break;
+ }
+ }
+ if (addArg)
+ {
+ jvmArguments.add(jvmArg);
+ }
+ }
+ }
+ else
+ {
+ jvmArguments.addAll(originalJvmArguments);
+ }
+ if (addJvmArguments != null)
+ {
+ jvmArguments.addAll(addJvmArguments);
+ }
+
+ if (startClass == null)
+ {
+ // this isn't always reliable
+ startClass = System.getProperty("sun.java.command");
+ }
+
+ List<String> applicationArguments = new ArrayList<>();
+ if (removeAppArguments != null)
+ {
+ Set<String> removeArgs = new HashSet<>(removeAppArguments);
+ for (String appArg : appArguments)
+ {
+ if (!removeArgs.contains(removeArgs))
+ {
+ applicationArguments.add(appArg);
+ }
+ }
+ }
+ else
+ {
+ applicationArguments.addAll(appArguments);
+ }
+ if (addAppArguments != null)
+ {
+ applicationArguments.addAll(addAppArguments);
+ }
+
+ List<String> command = new ArrayList<>();
+ // java command
+ command.add(javaBinary);
+
+ // classpath
+ command.add("-cp");
+ command.add(String.join(File.pathSeparator, classpathDirs));
+
+ // jvm args
+ command.addAll(jvmArguments);
+
+ // start class
+ command.add(startClass);
+
+ // application args
+ command.addAll(applicationArguments);
+
+ final ProcessBuilder builder = new ProcessBuilder(command);
+
+ if (Boolean.parseBoolean(System.getProperty("launcherprint", "false"))
+ || launcherprint)
+ {
+ syserr(debug, quiet,
+ "COMMAND: " + String.join(" ", builder.command()));
+ }
+
+ if (Boolean.parseBoolean(System.getProperty("launcherstop", "false"))
+ || (debug && launcherstop))
+ {
+ syserr(debug, quiet,
+ "System property 'launcherstop' is set and not 'false'. Exiting.");
+ System.exit(0);
+ }
+ try
+ {
+ builder.inheritIO();
+ Process process = builder.start();
+ if (launcherwait)
+ {
+ syserr(debug, quiet, "Launching application process");
+ exitValue = process.waitFor();
+ syserr(debug, quiet,
+ "Application process return with value " + exitValue);
+ }
+ else
+ {
+ int waitInt = 0;
+ syserr(debug, quiet,
+ "Wait time for application process is " + waitInt + "ms");
+ if (process.waitFor(waitInt, TimeUnit.MILLISECONDS))
+ {
+ exitValue = process.exitValue();
+ }
+ else
+ {
+ exitValue = -2;
+ }
+ }
+ syserr(debug, quiet, "Launcher process ending");
+ } catch (IOException e)
+ {
+ if (e.getMessage().toLowerCase(Locale.ROOT).contains("memory"))
+ {
+ syserr(true, quiet, "Caught a memory exception: " + e.getMessage());
+ // Probably the "Cannot allocate memory" error, try without the memory
+ // setting
+ ArrayList<String> commandNoMem = new ArrayList<>();
+ for (int i = 0; i < command.size(); i++)
+ {
+ if (!command.get(i).startsWith("-Xmx"))
+ {
+ commandNoMem.add(command.get(i));
+ }
+ }
+ final ProcessBuilder builderNoMem = new ProcessBuilder(
+ commandNoMem);
+ syserr(true, quiet, "Command without memory setting: "
+ + String.join(" ", builderNoMem.command()));
+ try
+ {
+ builderNoMem.inheritIO();
+ Process processNoMem = builderNoMem.start();
+ exitValue = processNoMem.waitFor();
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ else
+ {
+ e.printStackTrace();
+ }
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return exitValue;
+ }
+
+ public static void syserr(boolean debug, boolean quiet, String message)
+ {
+ if (debug && !quiet)
+ {
+ ErrorLog.errPrintln("DEBUG - " + message);
+ }
+ }
}
<?xml version="1.0" encoding="UTF-8"?>
-<install4j version="10.0.8" transformSequenceNumber="10">
+<install4j version="10.0.7" transformSequenceNumber="10">
<directoryPresets config="bin/Jalview" />
<application name="${compiler:JALVIEW_APPLICATION_NAME}" applicationId="${compiler:WINDOWS_APPLICATION_ID}" mediaDir="${compiler:BUILD_DIR}" lzmaCompression="true" shortName="${compiler:INTERNAL_ID}" publisher="University of Dundee" publisherWeb="https://www.jalview.org/" version="${compiler:JALVIEW_VERSION}" allPathsRelative="true" macVolumeId="5aac4968c304f65" javaMinVersion="${compiler:JAVA_MIN_VERSION}" javaMaxVersion="${compiler:JAVA_MAX_VERSION}" allowBetaVM="true" jdkMode="jdk" jdkName="JDK 11.0">
<searchSequence>
</files>
<launchers>
<launcher name="Jalview User Launcher" id="2823" customizedId="JALVIEW" menuName="${compiler:JALVIEW_APPLICATION_NAME}" icnsFile="${compiler:JALVIEW_DIR}/${compiler:MAC_ICONS_FILE}" customMacBundleIdentifier="true" macBundleIdentifier="${compiler:BUNDLE_ID}" fileset="734" addMacApplicationCategory="true" macApplicationCategory="public.app-category.education" useCustomMacosExecutableName="true" customMacosExecutableName="${compiler:JALVIEW_APPLICATION_NAME}">
- <executable name="${compiler:EXECUTABLE_NAME}" iconSet="true" iconFile="${compiler:JALVIEW_DIR}/${compiler:WINDOWS_ICONS_FILE}" stderrFile="~/.${compiler:UNIX_APPLICATION_FOLDER}-launcher.log" redirectStdout="true" stdoutFile="~/${compiler:UNIX_APPLICATION_FOLDER}-launcher.log" executableMode="gui" changeWorkingDirectory="false" singleInstance="true" executionLevel="highestAvailable" checkConsoleParameter="true">
+ <executable name="${compiler:EXECUTABLE_NAME}" iconSet="true" iconFile="${compiler:JALVIEW_DIR}/${compiler:WINDOWS_ICONS_FILE}" stderrFile="~/.${compiler:UNIX_APPLICATION_FOLDER}-launcher.log" redirectStdout="true" stdoutFile="~/.${compiler:UNIX_APPLICATION_FOLDER}-launcher.log" executableMode="gui" changeWorkingDirectory="false" singleInstance="true" executionLevel="highestAvailable" checkConsoleParameter="true">
<versionInfo include="true" fileDescription="${compiler:sys.fullName}" legalCopyright="${compiler:COPYRIGHT_MESSAGE}" internalName="${compiler:INTERNAL_ID}" productName="${compiler:sys.fullName}" />
</executable>
<splashScreen width="640" height="480" bitmapFile="${compiler:JALVIEW_DIR}/${compiler:BACKGROUND}" textOverlay="true">
<versionLine x="85" y="109" text="version ${compiler:sys.version}" />
</text>
</splashScreen>
- <java mainClass="com.threerings.getdown.launcher.GetdownApp" vmParameters="-Dusedefaultappdir=true -Dpopulatedefaultappdir=true -Dappid=jalview -Dinstaller.template_version=${compiler:INSTALLER_TEMPLATE_VERSION} -Dinstaller.appdir="${launcher:sys.launcherDirectory}" -Dinstaller.application_folder="${compiler:APPLICATION_FOLDER}" -Dchannel.app_name="${compiler:JALVIEW_APPLICATION_NAME}"">
+ <java mainClass="com.threerings.getdown.launcher.GetdownApp" vmParameters="-Duserdefaultappdir=true -Dpopulatedefaultappdir=true -Dappid=jalview -Dinstaller.template_version=${compiler:INSTALLER_TEMPLATE_VERSION} -Dinstaller.appdir="${launcher:sys.launcherDirectory}" -Dinstaller.application_folder="${compiler:APPLICATION_FOLDER}" -Dchannel.app_name="${compiler:JALVIEW_APPLICATION_NAME}"">
<classPath>
<archive location="getdown-launcher.jar" failOnError="false" />
<archive location="${compiler:GETDOWN_INSTALL_DIR}/getdown-launcher.jar" failOnError="false" />
# -include-options [path to other .vmoption file]
# Uncomment these two lines to disable user-space automatic updates.
-#-Dnousedefaultappdir=true
+#-Dnouserdefaultappdir=true
#-Dsilent=noupdate</content>
</vmOptionsFile>
<infoPlist>${compiler:file("${compiler:INFO_PLIST_FILE_ASSOCIATIONS_FILE}")}</infoPlist>