Prepare for more flexible Java version parsing.
This preserves existing functionality, but accomplishes it with a general purpose method that can parse any Java version string, given a regular expression that matches all the number parts (which have to be in most to least significant order).
This commit is contained in:
@@ -562,15 +562,15 @@ public class Application
|
||||
|
||||
// check to see if we require a particular JVM version and have a supplied JVM
|
||||
vstr = (String)cdata.get("java_version");
|
||||
if (vstr != null) _javaMinVersion = (int)parseLong(vstr, "m.invalid_java_version");
|
||||
if (vstr != null) _javaMinVersion = parseLong(vstr, "m.invalid_java_version");
|
||||
// we support java_min_version as an alias of java_version; it better expresses the check
|
||||
// that's going on and better mirrors java_max_version
|
||||
vstr = (String)cdata.get("java_min_version");
|
||||
if (vstr != null) _javaMinVersion = (int)parseLong(vstr, "m.invalid_java_version");
|
||||
if (vstr != null) _javaMinVersion = parseLong(vstr, "m.invalid_java_version");
|
||||
|
||||
// check to see if we require a particular max JVM version and have a supplied JVM
|
||||
vstr = (String)cdata.get("java_max_version");
|
||||
if (vstr != null) _javaMaxVersion = (int)parseLong(vstr, "m.invalid_java_version");
|
||||
if (vstr != null) _javaMaxVersion = parseLong(vstr, "m.invalid_java_version");
|
||||
|
||||
// check to see if we require a particular JVM version and have a supplied JVM
|
||||
vstr = (String)cdata.get("java_exact_version_required");
|
||||
@@ -782,46 +782,37 @@ public class Application
|
||||
public boolean haveValidJavaVersion ()
|
||||
{
|
||||
// if we're doing no version checking, then yay!
|
||||
if (_javaMinVersion == 0 && _javaMaxVersion == 0) {
|
||||
return true;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (vmjar != null && vmjar.isMarkedValid()) return true;
|
||||
|
||||
// parse the version out of the java.version system property
|
||||
String verstr = System.getProperty("java.version");
|
||||
Matcher m = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(_\\d+)?.*").matcher(verstr);
|
||||
if (!m.matches()) {
|
||||
try {
|
||||
// parse the version out of the java.version system property
|
||||
long version = SysProps.parseJavaVersion(
|
||||
"java.version", "(\\d+)\\.(\\d+)\\.(\\d+)(_\\d+)?.*");
|
||||
|
||||
if (_javaExactVersionRequired) {
|
||||
if (version == _javaMinVersion) return true;
|
||||
else {
|
||||
log.warning("An exact Java VM version is required.", "current", version,
|
||||
"required", _javaMinVersion);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean minVersionOK = (_javaMinVersion == 0) || (version >= _javaMinVersion);
|
||||
boolean maxVersionOK = (_javaMaxVersion == 0) || (version <= _javaMaxVersion);
|
||||
return minVersionOK && maxVersionOK;
|
||||
|
||||
} catch (RuntimeException re) {
|
||||
// if we can't parse the java version we're in weird land and should probably just try
|
||||
// our luck with what we've got rather than try to download a new jvm
|
||||
log.warning("Unable to parse VM version, hoping for the best",
|
||||
"version", verstr, "needed", _javaMinVersion);
|
||||
"error", re, "needed", _javaMinVersion);
|
||||
return true;
|
||||
}
|
||||
|
||||
int major = Integer.parseInt(m.group(1));
|
||||
int minor = Integer.parseInt(m.group(2));
|
||||
int revis = Integer.parseInt(m.group(3));
|
||||
int patch = m.group(4) == null ? 0 : Integer.parseInt(m.group(4).substring(1));
|
||||
int version = patch + 100 * (revis + 100 * (minor + 100 * major));
|
||||
|
||||
if (_javaExactVersionRequired) {
|
||||
if (version == _javaMinVersion) {
|
||||
return true;
|
||||
} else {
|
||||
log.warning("An exact Java VM version is required.", "current", version,
|
||||
"required", _javaMinVersion);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean minVersionOK = (_javaMinVersion == 0) || (version >= _javaMinVersion);
|
||||
boolean maxVersionOK = (_javaMaxVersion == 0) || (version <= _javaMaxVersion);
|
||||
return minVersionOK && maxVersionOK;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1729,7 +1720,7 @@ public class Application
|
||||
protected long _trackingStart;
|
||||
protected int _trackingId;
|
||||
|
||||
protected int _javaMinVersion, _javaMaxVersion;
|
||||
protected long _javaMinVersion, _javaMaxVersion;
|
||||
protected boolean _javaExactVersionRequired;
|
||||
protected String _javaLocation;
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
package com.threerings.getdown.data;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* This class encapsulates all system properties that are read and processed by Getdown. Don't
|
||||
* stick a call to {@code System.getProperty} randomly into the code, put it in here and give it an
|
||||
@@ -79,4 +82,58 @@ public class SysProps
|
||||
public static int connectTimeout () {
|
||||
return Integer.getInteger("connect_timeout", 0);
|
||||
}
|
||||
|
||||
/** Parses a Java version system property using the supplied regular expression. The numbers
|
||||
* extracted from the regexp will be placed in each consecutive hundreds position in the
|
||||
* returned value.
|
||||
*
|
||||
* <p>For example, {@code java.version} takes the form {@code 1.8.0_31}, and with the regexp
|
||||
* {@code (\d+)\.(\d+)\.(\d+)(_\d+)?} we would parse {@code 1, 8, 0, 31} and combine them into
|
||||
* the final value {@code 1080031}.
|
||||
*
|
||||
* <p>Note that non-numeric characters matched by the regular expression will simply be
|
||||
* ignored, and optional groups which do not match are treated as zero in the final version
|
||||
* calculation.
|
||||
*
|
||||
* <p>One can instead parse {@code java.runtime.version} which takes the form {@code
|
||||
* 1.8.0_31-b13}. Using regexp {@code (\d+)\.(\d+)\.(\d+)_(\d+)-b(\d+)} we would parse
|
||||
* {@code 1, 8, 0, 31, 13} and combine them into a final value {@code 108003113}.
|
||||
*
|
||||
* <p>Other (or future) JVMs may provide different version properties which can be parsed as
|
||||
* desired using this general scheme as long as the numbers appear from left to right in order
|
||||
* of significance.
|
||||
*
|
||||
* @throws IllegalArgumentException if no system named {@code propName} exists, or if
|
||||
* {@code propRegex} does not match the returned version string.
|
||||
*/
|
||||
public static long parseJavaVersion (String propName, String propRegex) {
|
||||
String verstr = System.getProperty(propName);
|
||||
if (verstr == null) throw new IllegalArgumentException(
|
||||
"No system property '" + propName + "'.");
|
||||
|
||||
Matcher m = Pattern.compile(propRegex).matcher(verstr);
|
||||
if (!m.matches()) 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Getdown - application installer, patcher and launcher
|
||||
// Copyright (C) 2004-2014 Three Rings Design, Inc.
|
||||
// https://raw.github.com/threerings/getdown/master/LICENSE
|
||||
|
||||
package com.threerings.getdown.data;
|
||||
|
||||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class SysPropsTest {
|
||||
|
||||
@Test public void testParseJavaVersion () {
|
||||
long vers = SysProps.parseJavaVersion("java.version", "(\\d+)\\.(\\d+)\\.(\\d+)(_\\d+)?");
|
||||
assert(vers > 1060000);
|
||||
|
||||
long runVers = SysProps.parseJavaVersion("java.runtime.version",
|
||||
"(\\d+)\\.(\\d+)\\.(\\d+)(_\\d+)?(-b\\d+)?");
|
||||
assert(runVers > 106000000);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user