Parse and check the version of an unpacked JVM.
This relies on the existence of a 'release' file in the top-level of the unpacked JVM. If no 'release' file exists (or it can't be read) then we fall back to the old behavior which is to assume that an unpacked JVM meets the app's version requirements. This also assumes that the java_version_regex configured for the app is capable of parsing the version string in the release file. The release file appears to contain a string that matches the system property 'java.version', so if you are doing version shenanigans and using 'java.runtime.version', you need to do one of two things: 1. Make sure your regexp can handle missing bits and that the lack of said bits doesn't hose your version checks. For example, if you need 1.8.0_42-b15 and your version regexp turns that into 108004215, but the release file just contains 1.8.0_42 which your version regexp turns into 108004200, then you're going to have a problem. But if your minimum version is some previous patch release (say 1.8.0_25-b32) and the custom JVM you ship is 1.8.0_42, then you'll be OK because 108004200 > 108002532. 2. Create your own 'release' file in your custom packaged JVM (or modify the existing one) which contains a line with the following syntax: JAVA_VERSION="VVV" where VVV is the full version string that your regexp expects. It will be extracted and parsed with your regexp, and everything will be peachy.
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user