53 |
53 |
54 private static boolean versionsInitialized = false; |
54 private static boolean versionsInitialized = false; |
55 private static int jvm_major_version = 0; |
55 private static int jvm_major_version = 0; |
56 private static int jvm_minor_version = 0; |
56 private static int jvm_minor_version = 0; |
57 private static int jvm_security_version = 0; |
57 private static int jvm_security_version = 0; |
58 private static int jvm_update_version = 0; |
58 private static int jvm_patch_version = 0; |
59 private static int jvm_build_number = 0; |
59 private static int jvm_build_number = 0; |
60 private static String jvm_special_version = null; |
|
61 private static int jdk_major_version = 0; |
60 private static int jdk_major_version = 0; |
62 private static int jdk_minor_version = 0; |
61 private static int jdk_minor_version = 0; |
63 private static int jdk_security_version = 0; |
62 private static int jdk_security_version = 0; |
64 private static int jdk_update_version = 0; |
63 private static int jdk_patch_version = 0; |
65 private static int jdk_build_number = 0; |
64 private static int jdk_build_number = 0; |
66 private static String jdk_special_version = null; |
|
67 |
65 |
68 /** |
66 /** |
69 * In case you were wondering this method is called by java -version. |
67 * In case you were wondering this method is called by java -version. |
70 * Sad that it prints to stderr; would be nicer if default printed on |
68 * Sad that it prints to stderr; would be nicer if default printed on |
71 * stdout. |
69 * stdout. |
144 return jvm_minor_version; |
142 return jvm_minor_version; |
145 } |
143 } |
146 |
144 |
147 |
145 |
148 /** |
146 /** |
149 * Returns the security version of the running JVM if it's 1.6 or newer |
147 * Returns the security version of the running JVM |
150 * or any RE VM build. It will return 0 if it's an internal 1.5 or |
|
151 * 1.4.x build. |
|
152 * @since 1.6 |
148 * @since 1.6 |
153 */ |
149 */ |
154 public static synchronized int jvmSecurityVersion() { |
150 public static synchronized int jvmSecurityVersion() { |
155 if (!versionsInitialized) { |
151 if (!versionsInitialized) { |
156 initVersions(); |
152 initVersions(); |
157 } |
153 } |
158 return jvm_security_version; |
154 return jvm_security_version; |
159 } |
155 } |
160 |
156 |
161 /** |
157 /** |
162 * Returns the update release version of the running JVM if it's |
158 * Returns the patch release version of the running JVM |
163 * a RE build. It will return 0 if it's an internal build. |
159 * @since JDK9 |
164 * @since 1.6 |
160 */ |
165 */ |
161 public static synchronized int jvmPatchVersion() { |
166 public static synchronized int jvmUpdateVersion() { |
162 if (!versionsInitialized) { |
167 if (!versionsInitialized) { |
163 initVersions(); |
168 initVersions(); |
164 } |
169 } |
165 return jvm_patch_version; |
170 return jvm_update_version; |
166 } |
171 } |
167 |
172 |
168 /** |
173 public static synchronized String jvmSpecialVersion() { |
169 * Returns the build number of the running JVM |
174 if (!versionsInitialized) { |
|
175 initVersions(); |
|
176 } |
|
177 if (jvm_special_version == null) { |
|
178 jvm_special_version = getJvmSpecialVersion(); |
|
179 } |
|
180 return jvm_special_version; |
|
181 } |
|
182 public static native String getJvmSpecialVersion(); |
|
183 |
|
184 /** |
|
185 * Returns the build number of the running JVM if it's a RE build |
|
186 * It will return 0 if it's an internal build. |
|
187 * @since 1.6 |
170 * @since 1.6 |
188 */ |
171 */ |
189 public static synchronized int jvmBuildNumber() { |
172 public static synchronized int jvmBuildNumber() { |
190 if (!versionsInitialized) { |
173 if (!versionsInitialized) { |
191 initVersions(); |
174 initVersions(); |
226 } |
209 } |
227 return jdk_security_version; |
210 return jdk_security_version; |
228 } |
211 } |
229 |
212 |
230 /** |
213 /** |
231 * Returns the update release version of the running JDK if it's |
214 * Returns the patch release version of the running JDK |
232 * a RE build. It will return 0 if it's an internal build. |
215 * @since 9 |
233 * @since 1.6 |
216 */ |
234 */ |
217 public static synchronized int jdkPatchVersion() { |
235 public static synchronized int jdkUpdateVersion() { |
218 if (!versionsInitialized) { |
236 if (!versionsInitialized) { |
219 initVersions(); |
237 initVersions(); |
220 } |
238 } |
221 return jdk_patch_version; |
239 return jdk_update_version; |
222 } |
240 } |
223 |
241 |
224 /** |
242 public static synchronized String jdkSpecialVersion() { |
225 * Returns the build number of the running JDK |
243 if (!versionsInitialized) { |
|
244 initVersions(); |
|
245 } |
|
246 if (jdk_special_version == null) { |
|
247 jdk_special_version = getJdkSpecialVersion(); |
|
248 } |
|
249 return jdk_special_version; |
|
250 } |
|
251 public static native String getJdkSpecialVersion(); |
|
252 |
|
253 /** |
|
254 * Returns the build number of the running JDK if it's a RE build |
|
255 * It will return 0 if it's an internal build. |
|
256 * @since 1.6 |
226 * @since 1.6 |
257 */ |
227 */ |
258 public static synchronized int jdkBuildNumber() { |
228 public static synchronized int jdkBuildNumber() { |
259 if (!versionsInitialized) { |
229 if (!versionsInitialized) { |
260 initVersions(); |
230 initVersions(); |
261 } |
231 } |
262 return jdk_build_number; |
232 return jdk_build_number; |
263 } |
233 } |
264 |
234 |
265 // true if JVM exports the version info including the capabilities |
|
266 private static boolean jvmVersionInfoAvailable; |
|
267 private static synchronized void initVersions() { |
235 private static synchronized void initVersions() { |
268 if (versionsInitialized) { |
236 if (versionsInitialized) { |
269 return; |
237 return; |
270 } |
238 } |
271 jvmVersionInfoAvailable = getJvmVersionInfo(); |
239 if (!getJvmVersionInfo()) { |
272 if (!jvmVersionInfoAvailable) { |
240 throw new InternalError("Unable to obtain JVM version info"); |
273 // parse java.vm.version for older JVM before the |
|
274 // new JVM_GetVersionInfo is added. |
|
275 // valid format of the version string is: |
|
276 // n.n.n[_uu[c]][-<identifer>]-bxx |
|
277 CharSequence cs = System.getProperty("java.vm.version"); |
|
278 if (cs.length() >= 5 && |
|
279 Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' && |
|
280 Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' && |
|
281 Character.isDigit(cs.charAt(4))) { |
|
282 jvm_major_version = Character.digit(cs.charAt(0), 10); |
|
283 jvm_minor_version = Character.digit(cs.charAt(2), 10); |
|
284 jvm_security_version = Character.digit(cs.charAt(4), 10); |
|
285 cs = cs.subSequence(5, cs.length()); |
|
286 if (cs.charAt(0) == '_' && cs.length() >= 3 && |
|
287 Character.isDigit(cs.charAt(1)) && |
|
288 Character.isDigit(cs.charAt(2))) { |
|
289 int nextChar = 3; |
|
290 try { |
|
291 String uu = cs.subSequence(1, 3).toString(); |
|
292 jvm_update_version = Integer.valueOf(uu).intValue(); |
|
293 if (cs.length() >= 4) { |
|
294 char c = cs.charAt(3); |
|
295 if (c >= 'a' && c <= 'z') { |
|
296 jvm_special_version = Character.toString(c); |
|
297 nextChar++; |
|
298 } |
|
299 } |
|
300 } catch (NumberFormatException e) { |
|
301 // not conforming to the naming convention |
|
302 return; |
|
303 } |
|
304 cs = cs.subSequence(nextChar, cs.length()); |
|
305 } |
|
306 if (cs.charAt(0) == '-') { |
|
307 // skip the first character |
|
308 // valid format: <identifier>-bxx or bxx |
|
309 // non-product VM will have -debug|-release appended |
|
310 cs = cs.subSequence(1, cs.length()); |
|
311 String[] res = cs.toString().split("-"); |
|
312 for (String s : res) { |
|
313 if (s.charAt(0) == 'b' && s.length() == 3 && |
|
314 Character.isDigit(s.charAt(1)) && |
|
315 Character.isDigit(s.charAt(2))) { |
|
316 jvm_build_number = |
|
317 Integer.valueOf(s.substring(1, 3)).intValue(); |
|
318 break; |
|
319 } |
|
320 } |
|
321 } |
|
322 } |
|
323 } |
241 } |
324 getJdkVersionInfo(); |
242 getJdkVersionInfo(); |
325 versionsInitialized = true; |
243 versionsInitialized = true; |
326 } |
244 } |
327 |
245 |
328 // Gets the JVM version info if available and sets the jvm_*_version fields |
246 // Gets the JVM version info if available and sets the jvm_*_version fields |
329 // and its capabilities. |
247 // and its capabilities. |
330 // |
|
331 // Return false if not available which implies an old VM (Tiger or before). |
|
332 private static native boolean getJvmVersionInfo(); |
248 private static native boolean getJvmVersionInfo(); |
333 private static native void getJdkVersionInfo(); |
249 private static native void getJdkVersionInfo(); |
334 } |
250 } |
335 |
251 |
336 // Help Emacs a little because this file doesn't end in .java. |
252 // Help Emacs a little because this file doesn't end in .java. |