I need to work around a Java bug in JDK 1.5 which was fixed in 1.6. I'm using the following condition:
if (System.getProperty("java.version").startsWith("1.5.")) {
...
} else {
...
}
Will this work for other JVMs? Is there a better way to check this?
15 Answers 15
java.version is a system property that exists in every JVM. There are two possible formats for it:
- Java 8 or lower:
1.6.0_23,1.7.0,1.7.0_80,1.8.0_211 - Java 9 or higher:
9.0.1,11.0.4,12,12.0.1
Here is a trick to extract the major version: If it is a 1.x.y_z version string, extract the character at index 2 of the string. If it is a x.y.z version string, cut the string to its first dot character, if one exists.
private static int getVersion() {
String version = System.getProperty("java.version");
if(version.startsWith("1.")) {
version = version.substring(2, 3);
} else {
int dot = version.indexOf(".");
if(dot != -1) { version = version.substring(0, dot); }
} return Integer.parseInt(version);
}
Now you can check the version much more comfortably:
if(getVersion() < 6) {
// ...
}
10 Comments
double version = 1.6 and Double.parseDouble("1.6") should still yield the same bit pattern, right? Since we don't do arithmetics on the number (only a simple compare), even == will work as expected.Runtime.version()
Since Java 9, you can use Runtime.version(), which returns a Runtime.Version:
Runtime.Version version = Runtime.version();
4 Comments
What about getting the version from the package meta infos:
String version = Runtime.class.getPackage().getImplementationVersion();
Prints out something like:
1.7.0_13
3 Comments
Runtime.class.getPackage().getSpecificationVersion()Runtime.class.getPackage().getImplementationVersion() seems to return null on JDK9.These articles seem to suggest that checking for 1.5 or 1.6 prefix should work, as it follows proper version naming convention.
Sun Technical Articles
- J2SE SDK/JRE Version String Naming Convention
- Version 1.5.0 or 5.0?
- "J2SE also keeps the version number 1.5.0 (or 1.5) in some places that are visible only to developers, or where the version number is parsed by programs"
- "
java.versionsystem property"
- "
- "J2SE also keeps the version number 1.5.0 (or 1.5) in some places that are visible only to developers, or where the version number is parsed by programs"
- Version 1.6.0 Used by Developers
- "Java SE keeps the version number 1.6.0 (or 1.6) in some places that are visible only to developers, or where the version number is parsed by programs."
- "
java.versionsystem property"
- "
- "Java SE keeps the version number 1.6.0 (or 1.6) in some places that are visible only to developers, or where the version number is parsed by programs."
3 Comments
java.runtime.name, java.vendor, java.vm.{name,vendor}, java.vm.specification.{name,vendor} I believe the first two may be semi-standardized by the official JVM/JLS spec, and the rest may be sort of standard conventions by now. Depending on what exactly the use case is in the application, often one or more of those properties can be the deciding factor.The simplest way (java.specification.version):
double version = Double.parseDouble(System.getProperty("java.specification.version"));
if (version == 1.5) {
// 1.5 specific code
} else {
// ...
}
or something like (java.version):
String[] javaVersionElements = System.getProperty("java.version").split("\\.");
int major = Integer.parseInt(javaVersionElements[1]);
if (major == 5) {
// 1.5 specific code
} else {
// ...
}
or if you want to break it all up (java.runtime.version):
String discard, major, minor, update, build;
String[] javaVersionElements = System.getProperty("java.runtime.version").split("\\.|_|-b");
discard = javaVersionElements[0];
major = javaVersionElements[1];
minor = javaVersionElements[2];
update = javaVersionElements[3];
build = javaVersionElements[4];
1 Comment
java.runtime.version is broken for Java 9 (java.lang.ArrayIndexOutOfBoundsException).Example for Apache Commons Lang:
import org.apache.commons.lang.SystemUtils;
Float version = SystemUtils.JAVA_VERSION_FLOAT;
if (version < 1.4f) {
// legacy
} else if (SystemUtils.IS_JAVA_1_5) {
// 1.5 specific code
} else if (SystemUtils.isJavaVersionAtLeast(1.6f)) {
// 1.6 compatible code
} else {
// dodgy clause to catch 1.4 :)
}
6 Comments
version < 1.4f... What happens when version = 1.4f?version <= 1.4f.. Unfortunately SystemUtils does not provide a isJavaVersionLessThan method but then (fortunately) you could also put the legacy code in an else block, which is cleaner.1.4f fall back to legacy code?if (SystemUtils.IS_JAVA_1_5) { /* 1.5 specific code */ } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) { /* modern code */ } else { /* fall back to legacy code */ }. Specific code above, generic code below, fallback code at the very bottom.Just a note that in Java 9 and above, the naming convention is different. System.getProperty("java.version") returns "9" rather than "1.9".
1 Comment
Does not work, need --pos to evaluate double:
String version = System.getProperty("java.version");
System.out.println("version:" + version);
int pos = 0, count = 0;
for (; pos < version.length() && count < 2; pos++) {
if (version.charAt(pos) == '.') {
count++;
}
}
--pos; //EVALUATE double
double dversion = Double.parseDouble(version.substring(0, pos));
System.out.println("dversion:" + dversion);
return dversion;
}
Comments
Here's the implementation in JOSM:
/**
* Returns the Java version as an int value.
* @return the Java version as an int value (8, 9, etc.)
* @since 12130
*/
public static int getJavaVersion() {
String version = System.getProperty("java.version");
if (version.startsWith("1.")) {
version = version.substring(2);
}
// Allow these formats:
// 1.8.0_72-ea
// 9-ea
// 9
// 9.0.1
int dotPos = version.indexOf('.');
int dashPos = version.indexOf('-');
return Integer.parseInt(version.substring(0,
dotPos > -1 ? dotPos : dashPos > -1 ? dashPos : 1));
}
1 Comment
Flag link: "... does not disclose the author's affiliation. "If you can have dependency to apache utils you can use org.apache.commons.lang3.SystemUtils.
System.out.println("Is Java version at least 1.8: " + SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8));
Comments
Don't know another way of checking this, but this: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/System.html#getProperties()" implies "java.version" is a standard system property so I'd expect it to work with other JVMs.
Comments
Here is the answer from @mvanle, converted to Scala:
scala> val Array(javaVerPrefix, javaVerMajor, javaVerMinor, _, _) = System.getProperty("java.runtime.version").split("\\.|_|-b")
javaVerPrefix: String = 1
javaVerMajor: String = 8
javaVerMinor: String = 0
Comments
https://docs.oracle.com/javase/9/docs/api/java/lang/Runtime.Version.html#version--
Runtime.version().version()
For 17.0.1 it returns [17, 0, 1]
One can use Runtime.version().version().get(0) to get the major java version.
1 Comment
Since Java 10, use:
int required = 21;
int feature = Runtime.version().feature();
if (feature < required) {
throw new IllegalStateException(String.format("Java version is %d, required %d", feature, required));
}
Runtime.version().major() is deprecated
1 Comment
In kotlin:
/**
* Returns the major JVM version, e.g. 6 for Java 1.6, 8 for Java 8, 11 for Java 11 etc.
*/
public val jvmVersion: Int get() = System.getProperty("java.version").parseJvmVersion()
/**
* Returns the major JVM version, 1 for 1.1, 2 for 1.2, 3 for 1.3, 4 for 1.4, 5
* for 1.5 etc.
*/
fun String.parseJvmVersion(): Int {
val version: String = removePrefix("1.").takeWhile { it.isDigit() }
return version.toInt()
}