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 import java.util.Properties; 33 34 class VersionProps { 35 36 private static final String launcher_name = 37 "@@LAUNCHER_NAME@@"; 38 39 private static final String java_version = 40 "@@VERSION_SHORT@@"; 41 42 private static final String java_version_date = 43 "@@VERSION_DATE@@"; 44 45 private static final String java_runtime_name = 46 "@@RUNTIME_NAME@@"; 47 48 private static final String java_runtime_version = 49 "@@VERSION_STRING@@"; 50 51 private static final String VERSION_NUMBER = 52 "@@VERSION_NUMBER@@"; 53 54 private static final String VERSION_BUILD = 55 "@@VERSION_BUILD@@"; 56 57 private static final String VERSION_PRE = 58 "@@VERSION_PRE@@"; 59 60 private static final String VERSION_OPT = 61 "@@VERSION_OPT@@"; 62 63 private static final boolean isLTS = 64 "@@VERSION_OPT@@".startsWith("LTS"); 65 66 private static final String VENDOR_VERSION_STRING = 67 "@@VENDOR_VERSION_STRING@@"; 68 69 private static final String vendor_version = 70 (VENDOR_VERSION_STRING.length() > 0 71 ? " " + VENDOR_VERSION_STRING : ""); 72 73 public static void init(Properties props) { 74 props.setProperty("java.version", java_version); 75 props.setProperty("java.version.date", java_version_date); 76 props.setProperty("java.runtime.version", java_runtime_version); 77 props.setProperty("java.runtime.name", java_runtime_name); 78 if (VENDOR_VERSION_STRING.length() > 0) 79 props.setProperty("java.vendor.version", VENDOR_VERSION_STRING); 80 } 81 82 private static int parseVersionNumber(String version, int prevIndex, int index) { 83 if (index - prevIndex > 1 && 84 Character.digit(version.charAt(prevIndex), 10) <= 0) 85 throw new IllegalArgumentException("Leading zeros not supported (" + 86 version.substring(prevIndex, index) + ")"); 87 return Integer.parseInt(version, prevIndex, index, 10); 88 } 89 90 // This method is reflectively used by regression tests. 91 static List<Integer> parseVersionNumbers(String version) { 92 // Let's find the size of an array required to hold $VNUM components 93 int size = 0; 94 int prevIndex = 0; 95 do { 96 prevIndex = version.indexOf('.', prevIndex) + 1; 97 size++; 98 } while (prevIndex > 0); 99 Integer[] verNumbers = new Integer[size]; 100 101 // Fill in the array with $VNUM components 102 int n = 0; 103 prevIndex = 0; 104 int index = version.indexOf('.'); 105 while (index > -1) { 106 verNumbers[n] = parseVersionNumber(version, prevIndex, index); 107 prevIndex = index + 1; // Skip the period 108 index = version.indexOf('.', prevIndex); 109 n++; 110 } 111 verNumbers[n] = parseVersionNumber(version, prevIndex, version.length()); 112 113 if (verNumbers[0] == 0 || verNumbers[n] == 0) 114 throw new IllegalArgumentException("Leading/trailing zeros not allowed (" + 115 Arrays.toString(verNumbers) + ")"); 116 117 return List.of(verNumbers); 118 } 119 120 static List<Integer> versionNumbers() { 121 return parseVersionNumbers(VERSION_NUMBER); 122 } 123 124 static Optional<String> pre() { 125 return optionalOf(VERSION_PRE); 126 } 127 128 static Optional<Integer> build() { 129 return VERSION_BUILD.isEmpty() ? 130 Optional.empty() : 131 Optional.of(Integer.parseInt(VERSION_BUILD)); 132 } 133 134 static Optional<String> optional() { 135 return optionalOf(VERSION_OPT); 136 } 137 138 // Treat empty strings as value not being present 139 private static Optional<String> optionalOf(String value) { 140 if (!value.isEmpty()) { 141 return Optional.of(value); 142 } else { 143 return Optional.empty(); 144 } 145 } 146 147 /** 148 * In case you were wondering this method is called by java -version. 149 */ 150 public static void print(boolean err) { 151 print(err, false); 152 } 153 154 /** 155 * This is the same as print except that it adds an extra line-feed 156 * at the end, typically used by the -showversion in the launcher 157 */ 158 public static void println(boolean err) { 159 print(err, true); 160 } 161 162 /** 163 * Print version info. 164 */ 165 private static void print(boolean err, boolean newln) { 166 PrintStream ps = err ? System.err : System.out; 167 168 /* First line: platform version. */ 169 if (err) { 170 ps.println(launcher_name + " version \"" + java_version + "\"" 171 + " " + java_version_date 172 + (isLTS ? " LTS" : "")); 173 } else { 174 /* Use a format more in line with GNU conventions */ 175 ps.println(launcher_name + " " + java_version 176 + " " + java_version_date 177 + (isLTS ? " LTS" : "")); 178 } 179 180 /* Second line: runtime version (ie, libraries). */ 181 String jdk_debug_level = System.getProperty("jdk.debug", "release"); 182 if ("release".equals(jdk_debug_level)) { 183 /* Do not show debug level "release" builds */ 184 jdk_debug_level = ""; 185 } else { 186 jdk_debug_level = jdk_debug_level + " "; 187 } 188 189 ps.println(java_runtime_name + vendor_version 190 + " (" + jdk_debug_level + "build " + java_runtime_version + ")"); 191 192 /* Third line: JVM information. */ 193 String java_vm_name = System.getProperty("java.vm.name"); 194 String java_vm_version = System.getProperty("java.vm.version"); 195 String java_vm_info = System.getProperty("java.vm.info"); 196 ps.println(java_vm_name + vendor_version 197 + " (" + jdk_debug_level + "build " + java_vm_version + ", " 198 + java_vm_info + ")"); 199 200 } 201 202 }