1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package sun.misc; 28 import java.io.PrintStream; 29 30 public class Version { 31 // Android-changed: launcher_name, java_version, 32 // java_runtime_name and java_runtime_version. 33 private static final String launcher_name = ""; 34 private static final String java_version = AndroidHardcodedSystemProperties.JAVA_VERSION; 35 private static final String java_runtime_name = "Android Runtime"; 36 private static final String java_profile_name = ""; 37 private static final String java_runtime_version = "0.9"; 38 39 // Called by java.lang.System.<clinit> initSystemProperties()40 public static void initSystemProperties() { 41 System.setUnchangeableSystemProperty("java.version", java_version); 42 System.setUnchangeableSystemProperty("java.runtime.version", java_runtime_version); 43 System.setUnchangeableSystemProperty("java.runtime.name", java_runtime_name); 44 } 45 46 private static boolean versionsInitialized = false; 47 private static int jvm_major_version = 0; 48 private static int jvm_minor_version = 0; 49 private static int jvm_micro_version = 0; 50 private static int jvm_update_version = 0; 51 private static int jvm_build_number = 0; 52 private static String jvm_special_version = null; 53 private static int jdk_major_version = 0; 54 private static int jdk_minor_version = 0; 55 private static int jdk_micro_version = 0; 56 private static int jdk_update_version = 0; 57 private static int jdk_build_number = 0; 58 private static String jdk_special_version = null; 59 60 /** 61 * In case you were wondering this method is called by java -version. 62 * Sad that it prints to stderr; would be nicer if default printed on 63 * stdout. 64 */ print()65 public static void print() { 66 print(System.err); 67 } 68 69 /** 70 * This is the same as print except that it adds an extra line-feed 71 * at the end, typically used by the -showversion in the launcher 72 */ println()73 public static void println() { 74 print(System.err); 75 System.err.println(); 76 } 77 78 /** 79 * Give a stream, it will print version info on it. 80 */ print(PrintStream ps)81 public static void print(PrintStream ps) { 82 boolean isHeadless = false; 83 84 /* Report that we're running headless if the property is true */ 85 String headless = System.getProperty("java.awt.headless"); 86 if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) { 87 isHeadless = true; 88 } 89 90 /* First line: platform version. */ 91 ps.println(launcher_name + " version \"" + java_version + "\""); 92 93 /* Second line: runtime version (ie, libraries). */ 94 95 ps.print(java_runtime_name + " (build " + java_runtime_version); 96 97 if (java_profile_name.length() > 0) { 98 // profile name 99 ps.print(", profile " + java_profile_name); 100 } 101 102 if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) { 103 // embedded builds report headless state 104 ps.print(", headless"); 105 } 106 ps.println(')'); 107 108 /* Third line: JVM information. */ 109 String java_vm_name = System.getProperty("java.vm.name"); 110 String java_vm_version = System.getProperty("java.vm.version"); 111 String java_vm_info = System.getProperty("java.vm.info"); 112 ps.println(java_vm_name + " (build " + java_vm_version + ", " + 113 java_vm_info + ")"); 114 } 115 116 117 /** 118 * Returns the major version of the running JVM if it's 1.6 or newer 119 * or any RE VM build. It will return 0 if it's an internal 1.5 or 120 * 1.4.x build. 121 * 122 * @since 1.6 123 */ jvmMajorVersion()124 public static synchronized int jvmMajorVersion() { 125 if (!versionsInitialized) { 126 initVersions(); 127 } 128 return jvm_major_version; 129 } 130 131 /** 132 * Returns the minor version of the running JVM if it's 1.6 or newer 133 * or any RE VM build. It will return 0 if it's an internal 1.5 or 134 * 1.4.x build. 135 * @since 1.6 136 */ jvmMinorVersion()137 public static synchronized int jvmMinorVersion() { 138 if (!versionsInitialized) { 139 initVersions(); 140 } 141 return jvm_minor_version; 142 } 143 144 145 /** 146 * Returns the micro version of the running JVM if it's 1.6 or newer 147 * or any RE VM build. It will return 0 if it's an internal 1.5 or 148 * 1.4.x build. 149 * @since 1.6 150 */ jvmMicroVersion()151 public static synchronized int jvmMicroVersion() { 152 if (!versionsInitialized) { 153 initVersions(); 154 } 155 return jvm_micro_version; 156 } 157 158 /** 159 * Returns the update release version of the running JVM if it's 160 * a RE build. It will return 0 if it's an internal build. 161 * @since 1.6 162 */ jvmUpdateVersion()163 public static synchronized int jvmUpdateVersion() { 164 if (!versionsInitialized) { 165 initVersions(); 166 } 167 return jvm_update_version; 168 } 169 jvmSpecialVersion()170 public static synchronized String jvmSpecialVersion() { 171 if (!versionsInitialized) { 172 initVersions(); 173 } 174 if (jvm_special_version == null) { 175 jvm_special_version = getJvmSpecialVersion(); 176 } 177 return jvm_special_version; 178 } getJvmSpecialVersion()179 public static native String getJvmSpecialVersion(); 180 181 /** 182 * Returns the build number of the running JVM if it's a RE build 183 * It will return 0 if it's an internal build. 184 * @since 1.6 185 */ jvmBuildNumber()186 public static synchronized int jvmBuildNumber() { 187 if (!versionsInitialized) { 188 initVersions(); 189 } 190 return jvm_build_number; 191 } 192 193 /** 194 * Returns the major version of the running JDK. 195 * 196 * @since 1.6 197 */ jdkMajorVersion()198 public static synchronized int jdkMajorVersion() { 199 if (!versionsInitialized) { 200 initVersions(); 201 } 202 return jdk_major_version; 203 } 204 205 /** 206 * Returns the minor version of the running JDK. 207 * @since 1.6 208 */ jdkMinorVersion()209 public static synchronized int jdkMinorVersion() { 210 if (!versionsInitialized) { 211 initVersions(); 212 } 213 return jdk_minor_version; 214 } 215 216 /** 217 * Returns the micro version of the running JDK. 218 * @since 1.6 219 */ jdkMicroVersion()220 public static synchronized int jdkMicroVersion() { 221 if (!versionsInitialized) { 222 initVersions(); 223 } 224 return jdk_micro_version; 225 } 226 227 /** 228 * Returns the update release version of the running JDK if it's 229 * a RE build. It will return 0 if it's an internal build. 230 * @since 1.6 231 */ jdkUpdateVersion()232 public static synchronized int jdkUpdateVersion() { 233 if (!versionsInitialized) { 234 initVersions(); 235 } 236 return jdk_update_version; 237 } 238 jdkSpecialVersion()239 public static synchronized String jdkSpecialVersion() { 240 if (!versionsInitialized) { 241 initVersions(); 242 } 243 if (jdk_special_version == null) { 244 jdk_special_version = getJdkSpecialVersion(); 245 } 246 return jdk_special_version; 247 } getJdkSpecialVersion()248 public static native String getJdkSpecialVersion(); 249 250 /** 251 * Returns the build number of the running JDK if it's a RE build 252 * It will return 0 if it's an internal build. 253 * @since 1.6 254 */ jdkBuildNumber()255 public static synchronized int jdkBuildNumber() { 256 if (!versionsInitialized) { 257 initVersions(); 258 } 259 return jdk_build_number; 260 } 261 262 // true if JVM exports the version info including the capabilities 263 private static boolean jvmVersionInfoAvailable; initVersions()264 private static synchronized void initVersions() { 265 if (versionsInitialized) { 266 return; 267 } 268 jvmVersionInfoAvailable = getJvmVersionInfo(); 269 if (!jvmVersionInfoAvailable) { 270 // parse java.vm.version for older JVM before the 271 // new JVM_GetVersionInfo is added. 272 // valid format of the version string is: 273 // n.n.n[_uu[c]][-<identifer>]-bxx 274 CharSequence cs = System.getProperty("java.vm.version"); 275 if (cs.length() >= 5 && 276 Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' && 277 Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' && 278 Character.isDigit(cs.charAt(4))) { 279 jvm_major_version = Character.digit(cs.charAt(0), 10); 280 jvm_minor_version = Character.digit(cs.charAt(2), 10); 281 jvm_micro_version = Character.digit(cs.charAt(4), 10); 282 cs = cs.subSequence(5, cs.length()); 283 if (cs.charAt(0) == '_' && cs.length() >= 3) { 284 int nextChar = 0; 285 if (Character.isDigit(cs.charAt(1)) && 286 Character.isDigit(cs.charAt(2)) && 287 Character.isDigit(cs.charAt(3))) 288 { 289 nextChar = 4; 290 } else if (Character.isDigit(cs.charAt(1)) && 291 Character.isDigit(cs.charAt(2))) 292 { 293 nextChar = 3; 294 } 295 296 try { 297 String uu = cs.subSequence(1, nextChar).toString(); 298 jvm_update_version = Integer.valueOf(uu).intValue(); 299 if (cs.length() >= nextChar + 1) { 300 char c = cs.charAt(nextChar); 301 if (c >= 'a' && c <= 'z') { 302 jvm_special_version = Character.toString(c); 303 nextChar++; 304 } 305 } 306 } catch (NumberFormatException e) { 307 // not conforming to the naming convention 308 return; 309 } 310 cs = cs.subSequence(nextChar, cs.length()); 311 } 312 if (cs.charAt(0) == '-') { 313 // skip the first character 314 // valid format: <identifier>-bxx or bxx 315 // non-product VM will have -debug|-release appended 316 cs = cs.subSequence(1, cs.length()); 317 String[] res = cs.toString().split("-"); 318 for (String s : res) { 319 if (s.charAt(0) == 'b' && s.length() == 3 && 320 Character.isDigit(s.charAt(1)) && 321 Character.isDigit(s.charAt(2))) { 322 jvm_build_number = 323 Integer.valueOf(s.substring(1, 3)).intValue(); 324 break; 325 } 326 } 327 } 328 } 329 } 330 getJdkVersionInfo(); 331 versionsInitialized = true; 332 } 333 334 // Gets the JVM version info if available and sets the jvm_*_version fields 335 // and its capabilities. 336 // 337 // Return false if not available which implies an old VM (Tiger or before). getJvmVersionInfo()338 private static native boolean getJvmVersionInfo(); getJdkVersionInfo()339 private static native void getJdkVersionInfo(); 340 } 341 342 // Help Emacs a little because this file doesn't end in .java. 343 // 344 // Local Variables: *** 345 // mode: java *** 346 // End: *** 347