+
+ public static int JAVA_COMPILE_VERSION = 0;
+
+ public static int getJavaCompileVersion()
+ {
+ if (LaunchUtils.isJS)
+ {
+ return -1;
+ }
+ else if (JAVA_COMPILE_VERSION > 0)
+ {
+ return JAVA_COMPILE_VERSION;
+ }
+ String buildDetails = "jar:".concat(LaunchUtils.class
+ .getProtectionDomain().getCodeSource().getLocation().toString()
+ .concat("!" + "/.build_properties"));
+ try
+ {
+ URL localFileURL = new URL(buildDetails);
+ InputStream in = localFileURL.openStream();
+ Properties buildProperties = new Properties();
+ buildProperties.load(in);
+ in.close();
+ String JCV = buildProperties.getProperty("JAVA_COMPILE_VERSION",
+ null);
+ if (JCV == null)
+ {
+ Console.errPrintln(
+ "Could not obtain JAVA_COMPILE_VERSION for comparison");
+ return -2;
+ }
+ JAVA_COMPILE_VERSION = Integer.parseInt(JCV);
+ } catch (MalformedURLException e)
+ {
+ jalview.bin.Console.errPrintln("Could not find " + buildDetails);
+ return -3;
+ } catch (IOException e)
+ {
+ jalview.bin.Console.errPrintln("Could not load " + buildDetails);
+ return -4;
+ } catch (NumberFormatException e)
+ {
+ jalview.bin.Console
+ .errPrintln("Could not parse JAVA_COMPILE_VERSION");
+ return -5;
+ }
+
+ return JAVA_COMPILE_VERSION;
+ }
+
+ public static int JAVA_VERSION = 0;
+
+ public static int getJavaVersion()
+ {
+ if (LaunchUtils.isJS)
+ {
+ return -1;
+ }
+ else if (JAVA_VERSION > 0)
+ {
+ return JAVA_VERSION;
+ }
+ try
+ {
+ String JV = System.getProperty("java.version");
+ if (JV == null)
+ {
+ Console.errPrintln("Could not obtain java.version for comparison");
+ return -2;
+ }
+ if (JV.startsWith("1."))
+ {
+ JV = JV.substring(2);
+ }
+ JAVA_VERSION = JV.indexOf(".") == -1 ? Integer.parseInt(JV)
+ : Integer.parseInt(JV.substring(0, JV.indexOf(".")));
+ } catch (NumberFormatException e)
+ {
+ jalview.bin.Console.errPrintln("Could not parse java.version");
+ return -3;
+ }
+ return JAVA_VERSION;
+ }
+
+ public static boolean checkJavaVersion()
+ {
+ if (LaunchUtils.isJS)
+ {
+ return true;
+ }
+ String buildDetails = "jar:".concat(LaunchUtils.class
+ .getProtectionDomain().getCodeSource().getLocation().toString()
+ .concat("!" + "/.build_properties"));
+
+ int java_compile_version = getJavaCompileVersion();
+ int java_version = getJavaVersion();
+
+ if (java_compile_version <= 0 || java_version <= 0)
+ {
+ Console.errPrintln("Could not make Java version check");
+ return true;
+ }
+ // Warn if these java.version and JAVA_COMPILE_VERSION conditions exist
+ // Usually this means a Java 11 compiled JAR being run by a Java 11 JVM
+ if (java_version >= 11 && java_compile_version < 11)
+ {
+ return false;
+ }
+
+ 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;
+ }