1 /* 2 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.lang; 27 28 import java.io.PrintStream; 29 import java.util.Arrays; 30 import java.util.List; 31 import java.util.Optional; 32 33 class VersionProps { 34 35 private static final String launcher_name = 36 "@@LAUNCHER_NAME@@"; 37 38 private static final String java_version = 39 "@@VERSION_SHORT@@"; 40 41 private static final String java_version_date = 42 "@@VERSION_DATE@@"; 43 44 private static final String java_runtime_name = 45 "@@RUNTIME_NAME@@"; 46 47 private static final String java_runtime_version = 48 "@@VERSION_STRING@@"; 49 50 private static final String VERSION_NUMBER = 51 "@@VERSION_NUMBER@@"; 52 53 private static final String VERSION_BUILD = 54 "@@VERSION_BUILD@@"; 55 56 private static final String VERSION_PRE = 57 "@@VERSION_PRE@@"; 58 59 private static final String VERSION_OPT = 60 "@@VERSION_OPT@@"; 61 62 private static final boolean isLTS = 63 "@@VERSION_OPT@@".startsWith("LTS"); 64 65 private static final String VENDOR_VERSION_STRING = 66 "@@VENDOR_VERSION_STRING@@"; 67 68 private static final String vendor_version = 69 (!VENDOR_VERSION_STRING.isEmpty() 70 ? " " + VENDOR_VERSION_STRING : ""); 71 72 static { 73 init(); 74 } 75 76 public static void init() { 77 System.setProperty("java.version", java_version); 78 System.setProperty("java.version.date", java_version_date); 79 System.setProperty("java.runtime.version", java_runtime_version); 80 System.setProperty("java.runtime.name", java_runtime_name); 81 if (!VENDOR_VERSION_STRING.isEmpty()) 82 System.setProperty("java.vendor.version", VENDOR_VERSION_STRING); 83 } 84 85 private static int parseVersionNumber(String version, int prevIndex, int index) { 86 if (index - prevIndex > 1 && 87 Character.digit(version.charAt(prevIndex), 10) <= 0) 88 throw new IllegalArgumentException("Leading zeros not supported (" + 89 version.substring(prevIndex, index) + ")"); 90 return Integer.parseInt(version, prevIndex, index, 10); 91 } 92 93 // This method is reflectively used by regression tests. 94 static List<Integer> parseVersionNumbers(String version) { 95 // Let's find the size of an array required to hold $VNUM components 96 int size = 0; 97 int prevIndex = 0; 98 do { 99 prevIndex = version.indexOf('.', prevIndex) + 1; 100 size++; 101 } while (prevIndex > 0); 102 Integer[] verNumbers = new Integer[size]; 103 104 // Fill in the array with $VNUM components 105 int n = 0; 106 prevIndex = 0; 107 int index = version.indexOf('.'); 108 while (index > -1) { 109 verNumbers[n] = parseVersionNumber(version, prevIndex, index); 110 prevIndex = index + 1; // Skip the period 111 index = version.indexOf('.', prevIndex); 112 n++; 113 } 114 verNumbers[n] = parseVersionNumber(version, prevIndex, version.length()); 115 116 if (verNumbers[0] == 0 || verNumbers[n] == 0) 117 throw new IllegalArgumentException("Leading/trailing zeros not allowed (" + 118 Arrays.toString(verNumbers) + ")"); 119 120 return List.of(verNumbers); 121 } 122 123 static List<Integer> versionNumbers() { 124 return parseVersionNumbers(VERSION_NUMBER); 125 } 126 127 static Optional<String> pre() { 128 return optionalOf(VERSION_PRE); 129 } 130 131 static Optional<Integer> build() { 132 return VERSION_BUILD.isEmpty() ? 133 Optional.empty() : 134 Optional.of(Integer.parseInt(VERSION_BUILD)); 135 } 136 137 static Optional<String> optional() { 138 return optionalOf(VERSION_OPT); 139 } 140 141 // Treat empty strings as value not being present 142 private static Optional<String> optionalOf(String value) { 143 if (!value.isEmpty()) { 144 return Optional.of(value); 145 } else { 146 return Optional.empty(); 147 } 148 } 149 150 /** 151 * In case you were wondering this method is called by java -version. 152 */ 153 public static void print(boolean err) { 154 print(err, false); 155 } 156 157 /** 158 * This is the same as print except that it adds an extra line-feed 159 * at the end, typically used by the -showversion in the launcher 160 */ 161 public static void println(boolean err) { 162 print(err, true); 163 } 164 165 /** 166 * Print version info. 167 */ 168 private static void print(boolean err, boolean newln) { 169 PrintStream ps = err ? System.err : System.out; 170 171 /* First line: platform version. */ 172 if (err) { 173 ps.println(launcher_name + " version \"" + java_version + "\"" 174 + " " + java_version_date 175 + (isLTS ? " LTS" : "")); 176 } else { 177 /* Use a format more in line with GNU conventions */ 178 ps.println(launcher_name + " " + java_version 179 + " " + java_version_date 180 + (isLTS ? " LTS" : "")); 181 } 182 183 /* Second line: runtime version (ie, libraries). */ 184 String jdk_debug_level = System.getProperty("jdk.debug", "release"); 185 if ("release".equals(jdk_debug_level)) { 186 /* Do not show debug level "release" builds */ 187 jdk_debug_level = ""; 188 } else { 189 jdk_debug_level = jdk_debug_level + " "; 190 } 191 192 ps.println(java_runtime_name + vendor_version 193 + " (" + jdk_debug_level + "build " + java_runtime_version + ")"); 194 195 /* Third line: JVM information. */ 196 String java_vm_name = System.getProperty("java.vm.name"); 197 String java_vm_version = System.getProperty("java.vm.version"); 198 String java_vm_info = System.getProperty("java.vm.info"); 199 ps.println(java_vm_name + vendor_version 200 + " (" + jdk_debug_level + "build " + java_vm_version + ", " 201 + java_vm_info + ")"); 202 203 } 204 205 }