Merge branch 'develop' into improvement/JAL-4124_dont_duplacate_PAE_data_acrossviews
[jalview.git] / src / jalview / bin / Launcher.java
index a87d322..e1415be 100644 (file)
@@ -50,28 +50,7 @@ public class Launcher
 {
   private final static String startClass = "jalview.bin.Jalview";
 
-  private static boolean checkJVMSymlink(String testBin)
-  {
-    File testBinFile = new File(testBin);
-    if (!testBinFile.exists())
-    {
-      return false;
-    }
-    File targetFile = null;
-    try
-    {
-      targetFile = testBinFile.getCanonicalFile();
-    } catch (IOException e)
-    {
-      return false;
-    }
-    if (targetFile != null && ("java".equals(targetFile.getName())
-            || "java.exe".equals(targetFile.getName())))
-    {
-      return true;
-    }
-    return false;
-  }
+  private final static String headlessProperty = "java.awt.headless";
 
   /**
    * main method for jalview.bin.Launcher. This restarts the same JRE's JVM with
@@ -85,53 +64,27 @@ public class Launcher
   {
     if (!LaunchUtils.checkJavaVersion())
     {
-      System.err.println("WARNING - The Java version being used (Java "
-              + LaunchUtils.getJavaVersion()
-              + ") may lead to problems. This installation of Jalview should be used with Java "
-              + LaunchUtils.getJavaCompileVersion() + ".");
-    }
-    final String appName = ChannelProperties.getProperty("app_name");
-    final String javaBinDir = System.getProperty("java.home")
-            + File.separator + "bin" + File.separator;
-    String javaBin = null;
-    if (javaBin == null && checkJVMSymlink(javaBinDir + appName))
-    {
-      javaBin = javaBinDir + appName;
-    }
-    if (javaBin == null && checkJVMSymlink(javaBinDir + "Jalview"))
-    {
-      javaBin = javaBinDir + "Jalview";
-    }
-    if (javaBin == null)
-    {
-      javaBin = "java";
-    }
-
-    List<String> command = new ArrayList<>();
-    command.add(javaBin);
-
-    String memSetting = null;
-
-    boolean isAMac = System.getProperty("os.name").indexOf("Mac") > -1;
-
-    for (String jvmArg : ManagementFactory.getRuntimeMXBean()
-            .getInputArguments())
-    {
-      command.add(jvmArg);
+      jalview.bin.Console
+              .errPrintln("WARNING - The Java version being used (Java "
+                      + LaunchUtils.getJavaVersion()
+                      + ") may lead to problems. This installation of Jalview should be used with Java "
+                      + LaunchUtils.getJavaCompileVersion() + ".");
     }
-    command.add("-cp");
-    command.add(ManagementFactory.getRuntimeMXBean().getClassPath());
 
     String jvmmempc = null;
     String jvmmemmax = null;
     boolean debug = false;
     boolean wait = true;
     boolean quiet = false;
+    boolean headless = false;
+    boolean gui = false;
+    boolean stdout = false;
     // must set --debug before --launcher...
     boolean launcherstop = false;
     boolean launcherprint = false;
     boolean launcherwait = false;
     ArrayList<String> arguments = new ArrayList<>();
+    String previousArg = null;
     for (String arg : args)
     {
       if (arg.equals("--debug"))
@@ -142,6 +95,19 @@ public class Launcher
       {
         quiet = true;
       }
+      if (arg.equals("--headless"))
+      {
+        headless = true;
+      }
+      if (arg.equals("--gui"))
+      {
+        gui = true;
+      }
+      if (arg.equals("--output=-")
+              || (arg.equals("-") && "--output".equals(previousArg)))
+      {
+        stdout = true;
+      }
       if (debug && arg.equals("--launcherprint"))
       {
         launcherprint = true;
@@ -159,6 +125,7 @@ public class Launcher
       {
         wait = false;
       }
+      previousArg = arg;
       // Don't add the --launcher... args to Jalview launch
       if (arg.startsWith("--launcher"))
       {
@@ -199,6 +166,29 @@ public class Launcher
         arguments.add(arg);
       }
     }
+    if (gui)
+    {
+      // --gui takes precedence over --headless
+      headless = false;
+    }
+
+    final String appName = ChannelProperties.getProperty("app_name");
+
+    // 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);
+
+    String memSetting = null;
+
+    for (String jvmArg : ManagementFactory.getRuntimeMXBean()
+            .getInputArguments())
+    {
+      command.add(jvmArg);
+    }
+    command.add("-cp");
+    command.add(ManagementFactory.getRuntimeMXBean().getClassPath());
 
     // use saved preferences if no cmdline args
     boolean useCustomisedSettings = LaunchUtils
@@ -221,6 +211,7 @@ public class Launcher
     boolean memSet = false;
     boolean dockIcon = false;
     boolean dockName = false;
+    boolean headlessProp = false;
     for (int i = 0; i < command.size(); i++)
     {
       String arg = command.get(i);
@@ -241,6 +232,10 @@ public class Launcher
       {
         dockName = true;
       }
+      else if (arg.startsWith("-D" + headlessProperty + "="))
+      {
+        headlessProp = true;
+      }
     }
 
     if (!memSet)
@@ -255,7 +250,7 @@ public class Launcher
       }
     }
 
-    if (isAMac)
+    if (LaunchUtils.isMac)
     {
       if (!dockIcon)
       {
@@ -276,11 +271,16 @@ public class Launcher
                 + appName);
       }
     }
+    if (headless && !headlessProp)
+    {
+      System.setProperty(headlessProperty, "true");
+      command.add("-D" + headlessProperty + "=true");
+    }
 
     String scalePropertyArg = HiDPISetting.getScalePropertyArg();
     if (scalePropertyArg != null)
     {
-      sysout(debug, quiet, "Running " + startClass + " with scale setting "
+      syserr(debug, quiet, "Running " + startClass + " with scale setting "
               + scalePropertyArg);
       command.add(scalePropertyArg);
     }
@@ -293,10 +293,10 @@ public class Launcher
     if ((Boolean.parseBoolean(System.getProperty("launcherprint", "false"))
             || launcherprint))
     {
-      sysout(debug, quiet,
+      syserr(debug, quiet,
               "LAUNCHER COMMAND: " + String.join(" ", builder.command()));
     }
-    sysout(debug, quiet,
+    syserr(debug, quiet,
             "Running " + startClass + " with "
                     + (memSetting == null ? "no memory setting"
                             : ("memory setting " + memSetting)));
@@ -304,7 +304,7 @@ public class Launcher
     if (Boolean.parseBoolean(System.getProperty("launcherstop", "false"))
             || (debug && launcherstop))
     {
-      sysout(debug, quiet,
+      syserr(debug, quiet,
               "System property 'launcherstop' is set and not 'false'. Exiting.");
       System.exit(0);
     }
@@ -314,22 +314,23 @@ public class Launcher
       Process process = builder.start();
       if (wait || launcherwait)
       {
-        sysout(debug, quiet, "Launching application process");
+        syserr(debug, quiet, "Launching application process");
         process.waitFor();
       }
       else
       {
         int waitInt = 0;
-        sysout(debug, quiet,
+        syserr(debug, quiet,
                 "Wait time for application process is " + waitInt + "ms");
         process.waitFor(waitInt, TimeUnit.MILLISECONDS);
       }
-      sysout(debug, quiet, "Launcher process ending");
+      syserr(debug, quiet, "Launcher process ending");
     } catch (IOException e)
     {
       if (e.getMessage().toLowerCase(Locale.ROOT).contains("memory"))
       {
-        System.err.println("Caught a memory exception: " + e.getMessage());
+        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<>();
@@ -342,7 +343,7 @@ public class Launcher
         }
         final ProcessBuilder builderNoMem = new ProcessBuilder(
                 commandNoMem);
-        System.err.println("Command without memory setting: "
+        jalview.bin.Console.errPrintln("Command without memory setting: "
                 + String.join(" ", builderNoMem.command()));
         try
         {
@@ -364,11 +365,11 @@ public class Launcher
     }
   }
 
-  private static void sysout(boolean debug, boolean quiet, String message)
+  private static void syserr(boolean debug, boolean quiet, String message)
   {
     if (debug && !quiet)
     {
-      System.out.println("LAUNCHERDEBUG - " + message);
+      jalview.bin.Console.errPrintln("LAUNCHERDEBUG - " + message);
     }
   }