/** * 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 * System.getProperty("java.vm.name").startWith(name). * * @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() { } }