diff --git a/src/main/java/com/threerings/getdown/data/Application.java b/src/main/java/com/threerings/getdown/data/Application.java index d9691d8..6ed0882 100644 --- a/src/main/java/com/threerings/getdown/data/Application.java +++ b/src/main/java/com/threerings/getdown/data/Application.java @@ -790,10 +790,6 @@ public class Application // if we're doing no version checking, then yay! if (_javaMinVersion == 0 && _javaMaxVersion == 0) return true; - // if we have a fully unpacked VM assume it is the right version (TODO: don't) - Resource vmjar = getJavaVMResource(); - if (vmjar != null && vmjar.isMarkedValid()) return true; - try { // parse the version out of the java.version (or custom) system property long version = SysProps.parseJavaVersion(_javaVersionProp, _javaVersionRegex); @@ -801,6 +797,26 @@ public class Application log.info("Checking Java version", "current", version, "wantMin", _javaMinVersion, "wantMax", _javaMaxVersion); + // if we have an unpacked VM, check the 'release' file for its version + Resource vmjar = getJavaVMResource(); + if (vmjar != null && vmjar.isMarkedValid()) { + File vmdir = new File(_appdir, LaunchUtil.LOCAL_JAVA_DIR); + File relfile = new File(vmdir, "release"); + if (!relfile.exists()) { + log.warning("Unpacked JVM missing 'release' file. Assuming valid version."); + return true; + } + + long vmvers = VersionUtil.readReleaseVersion(relfile, _javaVersionRegex); + if (vmvers == 0L) { + log.warning("Unable to read version from 'release' file. Assuming valid."); + return true; + } + + version = vmvers; + log.info("Checking version of unpacked JVM [vers=" + version + "]."); + } + if (_javaExactVersionRequired) { if (version == _javaMinVersion) return true; else { diff --git a/src/main/java/com/threerings/getdown/data/SysProps.java b/src/main/java/com/threerings/getdown/data/SysProps.java index 3359b24..02b910a 100644 --- a/src/main/java/com/threerings/getdown/data/SysProps.java +++ b/src/main/java/com/threerings/getdown/data/SysProps.java @@ -5,8 +5,7 @@ package com.threerings.getdown.data; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import com.threerings.getdown.util.VersionUtil; /** * This class encapsulates all system properties that are read and processed by Getdown. Don't @@ -111,29 +110,9 @@ public class SysProps if (verstr == null) throw new IllegalArgumentException( "No system property '" + propName + "'."); - Matcher m = Pattern.compile(propRegex).matcher(verstr); - if (!m.matches()) throw new IllegalArgumentException( + long vers = VersionUtil.parseJavaVersion(propRegex, verstr); + if (vers == 0L) throw new IllegalArgumentException( "Regexp '" + propRegex + "' does not match '" + verstr + "' (from " + propName + ")"); - - long vers = 0L; - for (int ii = 1; ii <= m.groupCount(); ii++) { - String valstr = m.group(ii); - int value = (valstr == null) ? 0 : parseInt(valstr); - vers *= 100; - vers += value; - } return vers; } - - private static int parseInt (String str) { - int value = 0; - for (int ii = 0, ll = str.length(); ii < ll; ii++) { - char c = str.charAt(ii); - if (c >= '0' && c <= '9') { - value *= 10; - value += (c - '0'); - } - } - return value; - } } diff --git a/src/main/java/com/threerings/getdown/util/VersionUtil.java b/src/main/java/com/threerings/getdown/util/VersionUtil.java index cc1cb5d..3a6cee4 100644 --- a/src/main/java/com/threerings/getdown/util/VersionUtil.java +++ b/src/main/java/com/threerings/getdown/util/VersionUtil.java @@ -9,14 +9,18 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.InputStreamReader; +import java.io.FileReader; import java.io.IOException; +import java.io.InputStreamReader; import java.io.PrintStream; import java.io.Reader; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.samskivert.io.StreamUtil; import com.samskivert.util.StringUtil; +import com.threerings.getdown.data.SysProps; import static com.threerings.getdown.Log.log; /** @@ -50,8 +54,7 @@ public class VersionUtil /** * Writes a version number to a file. */ - public static void writeVersion (File vfile, long version) - throws IOException + public static void writeVersion (File vfile, long version) throws IOException { PrintStream out = new PrintStream(new FileOutputStream(vfile)); try { @@ -62,4 +65,63 @@ public class VersionUtil StreamUtil.close(out); } } + + /** + * Parses {@code versStr} using {@code versRegex} into a (long) integer version number. + * @see SysProps#parseJavaVersion + */ + public static long parseJavaVersion (String versRegex, String versStr) + { + Matcher m = Pattern.compile(versRegex).matcher(versStr); + if (!m.matches()) return 0L; + + long vers = 0L; + for (int ii = 1; ii <= m.groupCount(); ii++) { + String valstr = m.group(ii); + int value = (valstr == null) ? 0 : parseInt(valstr); + vers *= 100; + vers += value; + } + return vers; + } + + /** + * Reads and parses the version from the {@code release} file bundled with a JVM. + */ + public static long readReleaseVersion (File relfile, String versRegex) + { + try { + BufferedReader in = new BufferedReader(new FileReader(relfile)); + String line = null, relvers = null; + while ((line = in.readLine()) != null) { + if (line.startsWith("JAVA_VERSION=")) { + relvers = line.substring("JAVA_VERSION=".length()).replace('"', ' ').trim(); + } + } + in.close(); + + if (relvers == null) { + log.warning("No JAVA_VERSION line in 'release' file", "file", relfile); + return 0L; + } + return parseJavaVersion(versRegex, relvers); + + } catch (Exception e) { + log.warning("Failed to read version from 'release' file", "file", relfile, e); + return 0L; + } + + } + + private static int parseInt (String str) { + int value = 0; + for (int ii = 0, ll = str.length(); ii < ll; ii++) { + char c = str.charAt(ii); + if (c >= '0' && c <= '9') { + value *= 10; + value += (c - '0'); + } + } + return value; + } }