JAL-3820 JAL-4189 Move checks for java executable symlinks to LaunchUtils ready for...
[jalview.git] / src / jalview / util / LaunchUtils.java
index 5bd4a08..784eb5a 100644 (file)
@@ -32,6 +32,16 @@ import java.util.Properties;
 public class LaunchUtils
 {
 
+  // setting these is LaunchUtils so don't need to import Platform
+  public final static boolean isMac = System.getProperty("os.name")
+          .indexOf("Mac") > -1;
+
+  public final static boolean isWindows = System.getProperty("os.name")
+          .indexOf("Win") > -1;
+
+  private static boolean isJS = /** @j2sNative true || */
+          false;
+
   public static void loadChannelProps(File dir)
   {
     ChannelProperties.loadProps(dir);
@@ -81,7 +91,7 @@ public class LaunchUtils
 
   public static int getJavaCompileVersion()
   {
-    if (Platform.isJS())
+    if (LaunchUtils.isJS)
     {
       return -1;
     }
@@ -129,7 +139,7 @@ public class LaunchUtils
 
   public static int getJavaVersion()
   {
-    if (Platform.isJS())
+    if (LaunchUtils.isJS)
     {
       return -1;
     }
@@ -161,7 +171,7 @@ public class LaunchUtils
 
   public static boolean checkJavaVersion()
   {
-    if (Platform.isJS())
+    if (LaunchUtils.isJS)
     {
       return true;
     }
@@ -186,4 +196,88 @@ public class LaunchUtils
 
     return true;
   }
+
+  public static String findJavaBin(boolean winConsole)
+  {
+    return findJavaBin(System.getProperty("java.home"), winConsole, true);
+  }
+
+  /*
+   * Returns a string path to the most likely java binary wanted to run this
+   * installation of Jalview.
+   * 
+   * @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  generic     Return a generic java command if not found.
+   */
+  public static String findJavaBin(String javaHome, boolean winConsole,
+          boolean generic)
+  {
+    String javaBin = null;
+    final String javaExe = winConsole ? "java.exe" : "javaw.exe";
+    final String java = "java";
+
+    if (javaHome != 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");
+
+      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, "Jalview", java, javaExe })
+      {
+        if (LaunchUtils.checkJVMSymlink(javaBinDir + name, winConsole))
+        {
+          javaBin = javaBinDir + name;
+          break;
+        }
+      }
+    }
+
+    if (javaBin == null && generic)
+    {
+      javaBin = LaunchUtils.isWindows ? javaExe : java;
+    }
+
+    return javaBin;
+  }
+
+  /*
+   * checkJVMSymlink returns true if the path in testBin *is* a java binary, or
+   * points to a java binary.
+   * @param  testBin     The binary or symbolic link to check
+   * @param  winConsole  whether we are in/want a Windows console (only relevant for Windows,
+   *                     determines whether we use java.exe or javaw.exe)
+   */
+  private static boolean checkJVMSymlink(String testBin, boolean winConsole)
+  {
+    File testBinFile = new File(testBin);
+    if (!testBinFile.exists())
+    {
+      return false;
+    }
+    File targetFile = null;
+    try
+    {
+      targetFile = testBinFile.getCanonicalFile();
+    } catch (IOException e)
+    {
+      return false;
+    }
+    final String javaExe = winConsole ? "java.exe" : "javaw.exe";
+    if (targetFile != null && ("java".equals(targetFile.getName())
+            || javaExe.equals(targetFile.getName())))
+    {
+      return true;
+    }
+    return false;
+  }
 }