import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.Locale;
+import javax.xml.bind.DatatypeConverter;
+
+import java.security.MessageDigest;
+
+import jalview.util.LaunchUtils;
+
import static com.threerings.getdown.Log.log;
/**
public class LaunchUtil
{
/** The directory into which a local VM installation should be unpacked. */
- public static final String LOCAL_JAVA_DIR = "java_vm";
+ public static final String LOCAL_JAVA_DIR = "jre";
/**
* Writes a <code>version.txt</code> file into the specified application directory and
return getJVMPath(appdir, false);
}
+ private static String jvmPath = null;
/**
* Reconstructs the path to the JVM used to launch this process.
*
*/
public static String getJVMPath (File appdir, boolean windebug)
{
- // first look in our application directory for an installed VM
- String vmpath = checkJVMPath(new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath(), windebug);
- if (vmpath == null && isMacOS()) {
- vmpath = checkJVMPath(new File(appdir, LOCAL_JAVA_DIR + "/Contents/Home").getAbsolutePath(), windebug);
+ if (jvmPath != null) {
+ return jvmPath;
}
+
+ // first look in our application directory for an installed VM
+ final String appDir = isMacOS() ?
+ (new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath()) + "/Contents/Home"
+ : new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath();
+
+ String javaBin = LaunchUtils.findJavaBin(appDir, windebug, false);
// then fall back to the VM in which we're already running
- if (vmpath == null) {
- vmpath = checkJVMPath(System.getProperty("java.home"), windebug);
+ if (javaBin == null) {
+ javaBin = LaunchUtils.findJavaBin(System.getProperty("java.home"), windebug, false);
}
// then throw up our hands and hope for the best
- if (vmpath == null) {
+ if (javaBin == null) {
+ javaBin = LaunchUtils.findJavaBin(null, windebug, true);
log.warning("Unable to find java [appdir=" + appdir +
", java.home=" + System.getProperty("java.home") + "]!");
- vmpath = "java";
}
// Oddly, the Mac OS X specific java flag -Xdock:name will only work if java is launched
if (isMacOS()) {
try {
File localVM = new File("/usr/bin/java").getCanonicalFile();
- if (localVM.equals(new File(vmpath).getCanonicalFile())) {
- vmpath = "/usr/bin/java";
+ if (localVM.equals(new File(javaBin).getCanonicalFile())) {
+ javaBin = "/usr/bin/java";
}
} catch (IOException ioe) {
log.warning("Failed to check Mac OS canonical VM path.", ioe);
}
}
- return vmpath;
+ jvmPath = javaBin;
+ return jvmPath;
}
+ private static String _getMD5FileChecksum (File file) {
+ // check md5 digest
+ String algo = "MD5";
+ String checksum = "";
+ try {
+ MessageDigest md = MessageDigest.getInstance(algo);
+ md.update(Files.readAllBytes(Paths.get(file.getAbsolutePath())));
+ byte[] digest = md.digest();
+ checksum = DatatypeConverter.printHexBinary(digest).toUpperCase(Locale.ROOT);
+ } catch (Exception e) {
+ System.out.println("Couldn't create "+algo+" digest of "+file.getPath());
+ }
+ return checksum;
+ }
+
/**
* Upgrades Getdown by moving an installation managed copy of the Getdown jar file over the
* non-managed copy (which would be used to run Getdown itself).
// we assume getdown's jar file size changes with every upgrade, this is not guaranteed,
// but in reality it will, and it allows us to avoid pointlessly upgrading getdown every
// time the client is updated which is unnecessarily flirting with danger
- if (!newgd.exists() || newgd.length() == curgd.length()) {
+ if (!newgd.exists())
+ {
return;
}
+
+ if (newgd.length() == curgd.length()) {
+ if (_getMD5FileChecksum(newgd).equals(_getMD5FileChecksum(curgd)))
+ {
+ return;
+ }
+ }
log.info("Updating Getdown with " + newgd + "...");
public static final boolean isLinux () { return _isLinux; }
/**
+ * Check if a symlink (or file) points to a JVM
+ */
+ 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;
+ }
+
+ /**
* Checks whether a Java Virtual Machine can be located in the supplied path.
*/
protected static String checkJVMPath (String vmhome, boolean windebug)
{
String vmbase = vmhome + File.separator + "bin" + File.separator;
- String vmpath = vmbase + "java";
+ String appName = System.getProperty("channel.app_name", "Jalview");
+ String vmpath = vmbase + appName;
+ if (checkJVMSymlink(vmpath)) {
+ return vmpath;
+ }
+ vmpath = vmbase + "Jalview";
+ if (checkJVMSymlink(vmpath)) {
+ return vmpath;
+ }
+ vmpath = vmbase + "java";
if (new File(vmpath).exists()) {
return vmpath;
}