org.yestech.lib.runtime.Jvm Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of yeslib Show documentation
Show all versions of yeslib Show documentation
A collection of classes that can be used across yestech artifacts/components, but must not be dependant
on any yestech component. Most of the code is utility type code. When more than a few classes are
found to be in a package or the package start to handle more that a few reposibilities then a new
independant component is created and the existing code in yeslib is ported to the new component.
/*
* Copyright LGPL3
* YES Technology Association
* http://yestech.org
*
* http://www.opensource.org/licenses/lgpl-3.0.html
*/
/*
*
* Original Author: Artie Copeland
* Last Modified Date: $DateTime: $
*/
package org.yestech.lib.runtime;
import java.lang.reflect.Method;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* @author $Author: $
* @version $Revision: $
*/
final public class Jvm {
/**
* Version info is parsed from system properties and stored here.
*/
public static final JvmVersion VERSION;
static {
VERSION = new JvmVersion(System.getProperties());
}
private Jvm() {
}
/**
* Get mega version (ie 1 in 1.2.3)
*
* @return Mega version
*/
public static int getMegaVersion() {
return VERSION.getMegaVersion();
}
/**
* Get major version (ie 2 in 1.2.3)
*
* @return Major version
*/
public static int getMajorVersion() {
return VERSION.getMajorVersion();
}
/**
* Get minor version (ie 3 in 1.2.3)
*
* @return Minor version
*/
public static int getMinorVersion() {
return VERSION.getMinorVersion();
}
/**
* Get patch level (ie 12 in 1.4.2_12)
*
* @return Patch level
*/
public static String getPatchLevel() {
return VERSION.getPatchLevel();
}
/**
* True if mega/major is 1.4
*
* @return True if 1.4
*/
public static boolean isJDK14() {
return VERSION.isJDK14();
}
/**
* True if mega/major is 1.5
*
* @return True if 1.5
*/
public static boolean isJDK15() {
return VERSION.isJDK15();
}
/**
* True if mega/major is 1.6
*
* @return True if 1.6
*/
public static boolean isJDK16() {
return VERSION.isJDK16();
}
/**
* True if mega/major is 1.7
*
* @return True if 1.7
*/
public static boolean isJDK17() {
return VERSION.isJDK17();
}
/**
* True if JDK is 1.5+
*
* @return True if JDK 1.5/1.6/1.7
*/
public static boolean isJDK15Compliant() {
return VERSION.getMajorVersion() >= 5;
}
/**
* True if JDK is 1.6+
*
* @return True if JDK 1.6/1.7
*/
public static boolean isJDK16Compliant() {
return VERSION.getMajorVersion() >= 6;
}
/**
* True if IBM JDK
*
* @return True if IBM JDK
*/
public static boolean isIBM() {
if (VERSION == null) {
// Our instrumentation for java.lang.reflect.Field can end up calling here while in for
// this class -- this avoids the NPE
return JvmVersion.thisVMisIBM();
}
return VERSION.isIBM();
}
public static void assertIsIbm() {
if (!isIBM()) {
throw new AssertionError("not ibm");
}
}
/**
* True if JRockit
*
* @return True if BEA Jrockit VM
*/
public static boolean isJRockit() {
return VERSION.isJRockit();
}
/**
* True if Azul
*
* @return True if Azul VM
*/
public static boolean isAzul() {
return VERSION.isAzul();
}
private static class JvmVersion {
private static final Pattern JVM_VERSION_PATTERN = Pattern
.compile("^(\\p{Digit})\\.(\\p{Digit})\\.(\\p{Digit})(?:[-_](.+))?$");
private static final Pattern IBM_SERVICE_RELEASE_PATTERN = Pattern
.compile("^[^-]+-\\p{Digit}{8}[^\\p{Space}]*\\p{Space}*\\(.*(SR\\p{Digit}+).*\\)$");
private final String vmVersion;
private final int mega;
private final int major;
private final int minor;
private final String patch;
private final boolean isIBM;
private final boolean isJRockit;
private final boolean isAzul;
/**
* Construct with system properties, which will be parsed to determine version. Looks at properties like java.version,
* java.runtime.version, jrockit.version, java.vm.name, and java.vendor.
*
* @param props Typically System.getProperties()
*/
public JvmVersion(final Properties props) {
this(javaVersion(props), runtimeVersion(props), isJRockit(props), isIBM(props), isAzul(props));
}
/**
* Construct with specific version information
*
* @param vendorVersion Version pattern like 1.4.2_12
* @param runtimeVersion Runtime version pattern like 1.4.2_12-269
* @param isJRockit True if BEA JRockit JVM
* @param isIBM True if IBM JVM
*/
private JvmVersion(final String vendorVersion, final String runtimeVersion, final boolean isJRockit,
final boolean isIBM, final boolean isAzul) {
this.isIBM = isIBM;
this.isJRockit = isJRockit;
this.isAzul = isAzul;
final Matcher versionMatcher = JVM_VERSION_PATTERN.matcher(vendorVersion);
if (versionMatcher.matches()) {
mega = Integer.parseInt(versionMatcher.group(1));
major = Integer.parseInt(versionMatcher.group(2));
minor = Integer.parseInt(versionMatcher.group(3));
String version_patch = versionMatcher.groupCount() == 4 ? versionMatcher.group(4) : null;
if (isIBM) {
final Matcher serviceReleaseMatcher = IBM_SERVICE_RELEASE_PATTERN.matcher(runtimeVersion);
if (serviceReleaseMatcher.matches()) {
String serviceRelease = serviceReleaseMatcher.groupCount() == 1 ? serviceReleaseMatcher.group(1)
.toLowerCase() : null;
if (null == version_patch && null == serviceRelease) {
patch = null;
} else if (null == version_patch) {
patch = serviceRelease;
} else if (null == serviceRelease) {
patch = version_patch;
} else {
patch = version_patch + serviceRelease;
}
} else {
throw new RuntimeException(vendorVersion + " : " + runtimeVersion);
}
} else {
patch = version_patch;
}
} else {
throw new RuntimeException(vendorVersion);
}
this.vmVersion = this.mega + "." + this.major + "." + this.minor + (null == patch ? "" : "_" + patch);
}
/**
* Given the history of SunOS and Java version numbering by Sun, this will return '1' for a long time to come. Mega
* version = 1 in 1.2.3
*
* @return Mega version
*/
public int getMegaVersion() {
return mega;
}
/**
* Get major version (ie 2 in 1.2.3)
*
* @return Major version
*/
public int getMajorVersion() {
return major;
}
/**
* Get minor version (ie 3 in 1.2.3)
*
* @return Minor version
*/
public int getMinorVersion() {
return minor;
}
/**
* Get patch level (ie 12 in 1.2.3_12)
*
* @return Patch level
*/
public String getPatchLevel() {
return patch;
}
/**
* @return True if JDK 1.4
*/
public boolean isJDK14() {
return mega == 1 && major == 4;
}
/**
* @return True if JDK 1.5
*/
public boolean isJDK15() {
return mega == 1 && major == 5;
}
/**
* @return True if JDK 1.6
*/
public boolean isJDK16() {
return mega == 1 && major == 6;
}
/**
* @return True if JDK 1.7
*/
public boolean isJDK17() {
return mega == 1 && major == 7;
}
/**
* @return True if IBM JVM
*/
public boolean isIBM() {
return isIBM;
}
/**
* @return True if Azul VM
*/
public boolean isAzul() {
return isAzul;
}
/**
* @return True if BEA JRockit
*/
public boolean isJRockit() {
return isJRockit;
}
/**
* @param o Other version
* @return True if other version has identical version string
*/
public boolean equals(final Object o) {
if (!(o instanceof JvmVersion)) {
return false;
}
final JvmVersion other = (JvmVersion) o;
return vmVersion.equals(other.vmVersion);
}
public int hashCode() {
return vmVersion.hashCode();
}
public String toString() {
return vmVersion;
}
private static String javaVersion(Properties props) {
return props.getProperty("java.version", "");
}
private static String runtimeVersion(Properties props) {
if (thisVMisIBM()) {
// It's not safe to read "java.runtime.version" from system properties until a certain point in startup
// Specifically there is a race to set this prop in com.ibm.misc.SystemIntialization.lastChanceHook() and the
// start of the management agent thread there (MNK-393)
return getIBMRuntimeVersion();
} else {
return props.getProperty("java.runtime.version", "");
}
}
static boolean thisVMisIBM() {
return isIBM(System.getProperties());
}
private static String getIBMRuntimeVersion() {
try {
Class c = Class.forName("com.ibm.misc.JavaRuntimeVersion");
Method m = c.getDeclaredMethod("getValue", new Class[]{});
m.setAccessible(true);
return (String) m.invoke(c, new Object[]{});
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
private static boolean isAzul(Properties props) {
return props.getProperty("java.vendor", "").toLowerCase().indexOf("azul") >= 0;
}
private static boolean isIBM(Properties props) {
return props.getProperty("java.vendor", "").toLowerCase().startsWith("ibm ");
}
private static boolean isJRockit(Properties props) {
return props.getProperty("jrockit.version") != null
|| props.getProperty("java.vm.name", "").toLowerCase().indexOf("jrockit") >= 0;
}
}
}