Home | History | Annotate | Download | only in misc
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1999, 2011, 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_runtime_version = "0.9";
     37 
     38     // Called by java.lang.System.<clinit>
     39     public static void initSystemProperties() {
     40         System.setUnchangeableSystemProperty("java.version", java_version);
     41         System.setUnchangeableSystemProperty("java.runtime.version", java_runtime_version);
     42         System.setUnchangeableSystemProperty("java.runtime.name", java_runtime_name);
     43     }
     44 
     45     private static boolean versionsInitialized = false;
     46     private static int jvm_major_version = 0;
     47     private static int jvm_minor_version = 0;
     48     private static int jvm_micro_version = 0;
     49     private static int jvm_update_version = 0;
     50     private static int jvm_build_number = 0;
     51     private static String jvm_special_version = null;
     52     private static int jdk_major_version = 0;
     53     private static int jdk_minor_version = 0;
     54     private static int jdk_micro_version = 0;
     55     private static int jdk_update_version = 0;
     56     private static int jdk_build_number = 0;
     57     private static String jdk_special_version = null;
     58 
     59     /**
     60      * In case you were wondering this method is called by java -version.
     61      * Sad that it prints to stderr; would be nicer if default printed on
     62      * stdout.
     63      */
     64     public static void print() {
     65         print(System.err);
     66     }
     67 
     68     /**
     69      * This is the same as print except that it adds an extra line-feed
     70      * at the end, typically used by the -showversion in the launcher
     71      */
     72     public static void println() {
     73         print(System.err);
     74         System.err.println();
     75     }
     76 
     77     /**
     78      * Give a stream, it will print version info on it.
     79      */
     80     public static void print(PrintStream ps) {
     81         boolean isHeadless = false;
     82 
     83         /* Report that we're running headless if the property is true */
     84 	String headless = System.getProperty("java.awt.headless");
     85 	if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) {
     86             isHeadless = true;
     87 	}
     88 
     89         /* First line: platform version. */
     90         ps.println(launcher_name + " version \"" + java_version + "\"");
     91 
     92         /* Second line: runtime version (ie, libraries). */
     93 
     94 	ps.print(java_runtime_name + " (build " + java_runtime_version);
     95 
     96 	if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) {
     97 	    // embedded builds report headless state
     98 	    ps.print(", headless");
     99 	}
    100 	ps.println(')');
    101 
    102         /* Third line: JVM information. */
    103         String java_vm_name    = System.getProperty("java.vm.name");
    104         String java_vm_version = System.getProperty("java.vm.version");
    105         String java_vm_info    = System.getProperty("java.vm.info");
    106         ps.println(java_vm_name + " (build " + java_vm_version + ", " +
    107                    java_vm_info + ")");
    108     }
    109 
    110 
    111     /**
    112      * Returns the major version of the running JVM if it's 1.6 or newer
    113      * or any RE VM build. It will return 0 if it's an internal 1.5 or
    114      * 1.4.x build.
    115      *
    116      * @since 1.6
    117      */
    118     public static synchronized int jvmMajorVersion() {
    119         if (!versionsInitialized) {
    120             initVersions();
    121         }
    122         return jvm_major_version;
    123     }
    124 
    125     /**
    126      * Returns the minor version of the running JVM if it's 1.6 or newer
    127      * or any RE VM build. It will return 0 if it's an internal 1.5 or
    128      * 1.4.x build.
    129      * @since 1.6
    130      */
    131     public static synchronized int jvmMinorVersion() {
    132         if (!versionsInitialized) {
    133             initVersions();
    134         }
    135         return jvm_minor_version;
    136     }
    137 
    138 
    139     /**
    140      * Returns the micro version of the running JVM if it's 1.6 or newer
    141      * or any RE VM build. It will return 0 if it's an internal 1.5 or
    142      * 1.4.x build.
    143      * @since 1.6
    144      */
    145     public static synchronized int jvmMicroVersion() {
    146         if (!versionsInitialized) {
    147             initVersions();
    148         }
    149         return jvm_micro_version;
    150     }
    151 
    152     /**
    153      * Returns the update release version of the running JVM if it's
    154      * a RE build. It will return 0 if it's an internal build.
    155      * @since 1.6
    156      */
    157     public static synchronized int jvmUpdateVersion() {
    158         if (!versionsInitialized) {
    159             initVersions();
    160         }
    161         return jvm_update_version;
    162     }
    163 
    164     public static synchronized String jvmSpecialVersion() {
    165         if (!versionsInitialized) {
    166             initVersions();
    167         }
    168         if (jvm_special_version == null) {
    169             jvm_special_version = getJvmSpecialVersion();
    170         }
    171         return jvm_special_version;
    172     }
    173     public static native String getJvmSpecialVersion();
    174 
    175     /**
    176      * Returns the build number of the running JVM if it's a RE build
    177      * It will return 0 if it's an internal build.
    178      * @since 1.6
    179      */
    180     public static synchronized int jvmBuildNumber() {
    181         if (!versionsInitialized) {
    182             initVersions();
    183         }
    184         return jvm_build_number;
    185     }
    186 
    187     /**
    188      * Returns the major version of the running JDK.
    189      *
    190      * @since 1.6
    191      */
    192     public static synchronized int jdkMajorVersion() {
    193         if (!versionsInitialized) {
    194             initVersions();
    195         }
    196         return jdk_major_version;
    197     }
    198 
    199     /**
    200      * Returns the minor version of the running JDK.
    201      * @since 1.6
    202      */
    203     public static synchronized int jdkMinorVersion() {
    204         if (!versionsInitialized) {
    205             initVersions();
    206         }
    207         return jdk_minor_version;
    208     }
    209 
    210     /**
    211      * Returns the micro version of the running JDK.
    212      * @since 1.6
    213      */
    214     public static synchronized int jdkMicroVersion() {
    215         if (!versionsInitialized) {
    216             initVersions();
    217         }
    218         return jdk_micro_version;
    219     }
    220 
    221     /**
    222      * Returns the update release version of the running JDK if it's
    223      * a RE build. It will return 0 if it's an internal build.
    224      * @since 1.6
    225      */
    226     public static synchronized int jdkUpdateVersion() {
    227         if (!versionsInitialized) {
    228             initVersions();
    229         }
    230         return jdk_update_version;
    231     }
    232 
    233     public static synchronized String jdkSpecialVersion() {
    234         if (!versionsInitialized) {
    235             initVersions();
    236         }
    237         if (jdk_special_version == null) {
    238             jdk_special_version = getJdkSpecialVersion();
    239         }
    240         return jdk_special_version;
    241     }
    242     public static native String getJdkSpecialVersion();
    243 
    244     /**
    245      * Returns the build number of the running JDK if it's a RE build
    246      * It will return 0 if it's an internal build.
    247      * @since 1.6
    248      */
    249     public static synchronized int jdkBuildNumber() {
    250         if (!versionsInitialized) {
    251             initVersions();
    252         }
    253         return jdk_build_number;
    254     }
    255 
    256     // true if JVM exports the version info including the capabilities
    257     private static boolean jvmVersionInfoAvailable;
    258     private static synchronized void initVersions() {
    259         if (versionsInitialized) {
    260             return;
    261         }
    262         jvmVersionInfoAvailable = getJvmVersionInfo();
    263         if (!jvmVersionInfoAvailable) {
    264             // parse java.vm.version for older JVM before the
    265             // new JVM_GetVersionInfo is added.
    266             // valid format of the version string is:
    267             // n.n.n[_uu[c]][-<identifer>]-bxx
    268             CharSequence cs = System.getProperty("java.vm.version");
    269             if (cs.length() >= 5 &&
    270                 Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' &&
    271                 Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' &&
    272                 Character.isDigit(cs.charAt(4))) {
    273                 jvm_major_version = Character.digit(cs.charAt(0), 10);
    274                 jvm_minor_version = Character.digit(cs.charAt(2), 10);
    275                 jvm_micro_version = Character.digit(cs.charAt(4), 10);
    276                 cs = cs.subSequence(5, cs.length());
    277                 if (cs.charAt(0) == '_' && cs.length() >= 3 &&
    278                     Character.isDigit(cs.charAt(1)) &&
    279                     Character.isDigit(cs.charAt(2))) {
    280                     int nextChar = 3;
    281                     try {
    282                         String uu = cs.subSequence(1, 3).toString();
    283                         jvm_update_version = Integer.parseInt(uu);
    284                         if (cs.length() >= 4) {
    285                             char c = cs.charAt(3);
    286                             if (c >= 'a' && c <= 'z') {
    287                                 jvm_special_version = Character.toString(c);
    288                                 nextChar++;
    289                             }
    290                         }
    291                     } catch (NumberFormatException e) {
    292                         // not conforming to the naming convention
    293                         return;
    294                     }
    295                     cs = cs.subSequence(nextChar, cs.length());
    296                 }
    297                 if (cs.charAt(0) == '-') {
    298                     // skip the first character
    299                     // valid format: <identifier>-bxx or bxx
    300                     // non-product VM will have -debug|-release appended
    301                     cs = cs.subSequence(1, cs.length());
    302                     String[] res = cs.toString().split("-");
    303                     for (String s : res) {
    304                         if (s.charAt(0) == 'b' && s.length() == 3 &&
    305                             Character.isDigit(s.charAt(1)) &&
    306                             Character.isDigit(s.charAt(2))) {
    307                             jvm_build_number =
    308                                 Integer.parseInt(s.substring(1, 3));
    309                             break;
    310                         }
    311                     }
    312                 }
    313             }
    314         }
    315         getJdkVersionInfo();
    316         versionsInitialized = true;
    317     }
    318 
    319     // Gets the JVM version info if available and sets the jvm_*_version fields
    320     // and its capabilities.
    321     //
    322     // Return false if not available which implies an old VM (Tiger or before).
    323     private static native boolean getJvmVersionInfo();
    324     private static native void getJdkVersionInfo();
    325 
    326 }
    327 
    328 // Help Emacs a little because this file doesn't end in .java.
    329 //
    330 // Local Variables: ***
    331 // mode: java ***
    332 // End: ***
    333