• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2006-2017 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.objenesis.strategy;
17 
18 import org.objenesis.ObjenesisException;
19 
20 import java.lang.reflect.Field;
21 
22 /**
23  * List of constants describing the currently used platform.
24  *
25  * @author Henri Tremblay
26  */
27 public final class PlatformDescription {
28 
29    /** JVM_NAME prefix for JRockit */
30    public static final String JROCKIT = "BEA";
31 
32    /** JVM_NAME prefix for GCJ */
33    public static final String GNU = "GNU libgcj";
34 
35    /** JVM_NAME prefix for Java HotSpot */
36    public static final String HOTSPOT = "Java HotSpot";
37 
38    /**
39     * JVM_NAME prefix for Java HotSpot
40     *
41     * @deprecated Use {@link #HOTSPOT} instead
42     */
43    @Deprecated
44    public static final String SUN = HOTSPOT;
45 
46    /** JVM_NAME prefix for the OpenJDK */
47    public static final String OPENJDK = "OpenJDK";
48 
49    /** JVM_NAME prefix for Aonix PERC */
50    public static final String PERC = "PERC";
51 
52    /** JVM_NAME prefix for Dalvik/Android */
53    public static final String DALVIK = "Dalvik";
54 
55    /** Java specification version */
56    public static final String SPECIFICATION_VERSION = System
57       .getProperty("java.specification.version");
58 
59    /** JVM version */
60    public static final String VM_VERSION = System.getProperty("java.runtime.version");
61 
62    /** JVM version */
63    public static final String VM_INFO = System.getProperty("java.vm.info");
64 
65    /** VM vendor version */
66    public static final String VENDOR_VERSION = System.getProperty("java.vm.version");
67 
68    /** VM vendor name */
69    public static final String VENDOR = System.getProperty("java.vm.vendor");
70 
71    /** JVM name */
72    public static final String JVM_NAME = System.getProperty("java.vm.name");
73 
74    /** Android version. Will be 0 for none android platform */
75    public static final int ANDROID_VERSION = getAndroidVersion();
76 
77    /** Flag telling if this version of Android is based on the OpenJDK */
78    public static final boolean IS_ANDROID_OPENJDK = getIsAndroidOpenJDK();
79 
80    /** Google App Engine version or null is we are not on GAE */
81    public static final String GAE_VERSION = getGaeRuntimeVersion();
82 
83    /**
84     * Describes the platform. Outputs Java version and vendor.
85     *
86     * @return Description of the current platform
87     */
describePlatform()88    public static String describePlatform() {
89       String desc = "Java " + SPECIFICATION_VERSION + " ("
90               + "VM vendor name=\"" + VENDOR + "\", "
91               + "VM vendor version=" + VENDOR_VERSION + ", "
92               + "JVM name=\"" + JVM_NAME + "\", "
93               + "JVM version=" + VM_VERSION + ", "
94               + "JVM info=" + VM_INFO;
95 
96       // Add the API level is it's an Android platform
97       int androidVersion = ANDROID_VERSION;
98       if(androidVersion != 0) {
99          desc += ", API level=" + ANDROID_VERSION;
100       }
101       desc += ")";
102 
103       return desc;
104    }
105 
106    /**
107     * Check if the current JVM is of the type passed in parameter. Normally, this will be a constant
108     * from this class. We basically do
109     * <code>System.getProperty("java.vm.name").startWith(name)</code>.
110     *
111     * @param name jvm name we are looking for
112     * @return if it's the requested JVM
113     */
isThisJVM(String name)114    public static boolean isThisJVM(String name) {
115       return JVM_NAME.startsWith(name);
116    }
117 
118    /**
119     * Check if this JVM is an Android JVM based on OpenJDK.
120     *
121     * @return if it's an Android version based on the OpenJDK. Will return false if this JVM isn't an Android JVM at all
122      */
isAndroidOpenJDK()123    public static boolean isAndroidOpenJDK() {
124       return IS_ANDROID_OPENJDK;
125    }
126 
getIsAndroidOpenJDK()127    private static boolean getIsAndroidOpenJDK() {
128       if(getAndroidVersion() == 0) {
129          return false; // Not android at all
130       }
131       // Sadly, Android N is still API 23. So we can't base ourselves on the API level to know if it is an OpenJDK
132       // version or not
133       String bootClasspath = System.getProperty("java.boot.class.path");
134       return bootClasspath != null && bootClasspath.toLowerCase().contains("core-oj.jar");
135    }
136 
isGoogleAppEngine()137    public static boolean isGoogleAppEngine() {
138       return GAE_VERSION != null;
139    }
140 
getGaeRuntimeVersion()141    private static String getGaeRuntimeVersion() {
142       return System.getProperty("com.google.appengine.runtime.version");
143    }
144 
getAndroidVersion()145    private static int getAndroidVersion() {
146       if(!isThisJVM(DALVIK)) {
147          return 0;
148       }
149       return getAndroidVersion0();
150    }
151 
getAndroidVersion0()152    private static int getAndroidVersion0() {
153       Class<?> clazz;
154       try {
155          clazz = Class.forName("android.os.Build$VERSION");
156       }
157       catch(ClassNotFoundException e) {
158          throw new ObjenesisException(e);
159       }
160       Field field;
161       try {
162          field = clazz.getField("SDK_INT");
163       }
164       catch(NoSuchFieldException e) {
165          // Might be a really old API (before 4), go for SDK
166          return getOldAndroidVersion(clazz);
167       }
168       int version;
169       try {
170          version = (Integer) field.get(null);
171       }
172       catch(IllegalAccessException e) {
173          throw new RuntimeException(e);
174       }
175       return version;
176    }
177 
getOldAndroidVersion(Class<?> versionClass)178    private static int getOldAndroidVersion(Class<?> versionClass) {
179       Field field;
180       try {
181          field = versionClass.getField("SDK");
182       }
183       catch(NoSuchFieldException e) {
184          throw new ObjenesisException(e);
185       }
186       String version;
187       try {
188          version = (String) field.get(null);
189       }
190       catch(IllegalAccessException e) {
191          throw new RuntimeException(e);
192       }
193       return Integer.parseInt(version);
194    }
195 
PlatformDescription()196    private PlatformDescription() {
197    }
198 }
199