blob: 802456768e2074ac962d0f08ad51e4d6875e1a9b [file] [log] [blame]
/**
* Copyright 2006-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.objenesis.strategy;
import org.objenesis.ObjenesisException;
import java.lang.reflect.Field;
/**
* List of constants describing the currently used platform.
*
* @author Henri Tremblay
*/
public final class PlatformDescription {
/** JVM_NAME prefix for JRockit */
public static final String JROCKIT = "BEA";
/** JVM_NAME prefix for GCJ */
public static final String GNU = "GNU libgcj";
/** JVM_NAME prefix for Java HotSpot */
public static final String HOTSPOT = "Java HotSpot";
/**
* JVM_NAME prefix for Java HotSpot
*
* @deprecated Use {@link #HOTSPOT} instead
*/
@Deprecated
public static final String SUN = HOTSPOT;
/** JVM_NAME prefix for the OpenJDK */
public static final String OPENJDK = "OpenJDK";
/** JVM_NAME prefix for Aonix PERC */
public static final String PERC = "PERC";
/** JVM_NAME prefix for Dalvik/Android */
public static final String DALVIK = "Dalvik";
/** Java specification version */
public static final String SPECIFICATION_VERSION = System
.getProperty("java.specification.version");
/** JVM version */
public static final String VM_VERSION = System.getProperty("java.runtime.version");
/** JVM version */
public static final String VM_INFO = System.getProperty("java.vm.info");
/** VM vendor version */
public static final String VENDOR_VERSION = System.getProperty("java.vm.version");
/** VM vendor name */
public static final String VENDOR = System.getProperty("java.vm.vendor");
/** JVM name */
public static final String JVM_NAME = System.getProperty("java.vm.name");
/** Android version. Will be 0 for none android platform */
public static final int ANDROID_VERSION = getAndroidVersion();
/** Flag telling if this version of Android is based on the OpenJDK */
public static final boolean IS_ANDROID_OPENJDK = getIsAndroidOpenJDK();
/** Google App Engine version or null is we are not on GAE */
public static final String GAE_VERSION = getGaeRuntimeVersion();
/**
* Describes the platform. Outputs Java version and vendor.
*
* @return Description of the current platform
*/
public static String describePlatform() {
String desc = "Java " + SPECIFICATION_VERSION + " ("
+ "VM vendor name=\"" + VENDOR + "\", "
+ "VM vendor version=" + VENDOR_VERSION + ", "
+ "JVM name=\"" + JVM_NAME + "\", "
+ "JVM version=" + VM_VERSION + ", "
+ "JVM info=" + VM_INFO;
// Add the API level is it's an Android platform
int androidVersion = ANDROID_VERSION;
if(androidVersion != 0) {
desc += ", API level=" + ANDROID_VERSION;
}
desc += ")";
return desc;
}
/**
* Check if the current JVM is of the type passed in parameter. Normally, this will be a constant
* from this class. We basically do
* <code>System.getProperty("java.vm.name").startWith(name)</code>.
*
* @param name jvm name we are looking for
* @return if it's the requested JVM
*/
public static boolean isThisJVM(String name) {
return JVM_NAME.startsWith(name);
}
/**
* Check if this JVM is an Android JVM based on OpenJDK.
*
* @return if it's an Android version based on the OpenJDK. Will return false if this JVM isn't an Android JVM at all
*/
public static boolean isAndroidOpenJDK() {
return IS_ANDROID_OPENJDK;
}
private static boolean getIsAndroidOpenJDK() {
if(getAndroidVersion() == 0) {
return false; // Not android at all
}
// Sadly, Android N is still API 23. So we can't base ourselves on the API level to know if it is an OpenJDK
// version or not
String bootClasspath = System.getProperty("java.boot.class.path");
return bootClasspath != null && bootClasspath.toLowerCase().contains("core-oj.jar");
}
public static boolean isGoogleAppEngine() {
return GAE_VERSION != null;
}
private static String getGaeRuntimeVersion() {
return System.getProperty("com.google.appengine.runtime.version");
}
private static int getAndroidVersion() {
if(!isThisJVM(DALVIK)) {
return 0;
}
return getAndroidVersion0();
}
private static int getAndroidVersion0() {
Class<?> clazz;
try {
clazz = Class.forName("android.os.Build$VERSION");
}
catch(ClassNotFoundException e) {
throw new ObjenesisException(e);
}
Field field;
try {
field = clazz.getField("SDK_INT");
}
catch(NoSuchFieldException e) {
// Might be a really old API (before 4), go for SDK
return getOldAndroidVersion(clazz);
}
int version;
try {
version = (Integer) field.get(null);
}
catch(IllegalAccessException e) {
throw new RuntimeException(e);
}
return version;
}
private static int getOldAndroidVersion(Class<?> versionClass) {
Field field;
try {
field = versionClass.getField("SDK");
}
catch(NoSuchFieldException e) {
throw new ObjenesisException(e);
}
String version;
try {
version = (String) field.get(null);
}
catch(IllegalAccessException e) {
throw new RuntimeException(e);
}
return Integer.parseInt(version);
}
private PlatformDescription() {
}
}