/**
* 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() {
}
}