# HG changeset patch # User ksrini # Date 1290559959 28800 # Node ID 906c58a8b849afc133e4b04048ac5702ed6f9715 # Parent fa827ef8c75ef3793a463a46bde3e37359e0f108 6452854: Provide a flag to print the java configuration Reviewed-by: darcy, mchung, sherman, dholmes, mduigou diff -r fa827ef8c75e -r 906c58a8b849 jdk/src/share/bin/java.c --- a/jdk/src/share/bin/java.c Wed Nov 24 07:43:06 2010 +0800 +++ b/jdk/src/share/bin/java.c Tue Nov 23 16:52:39 2010 -0800 @@ -65,6 +65,7 @@ static jboolean showVersion = JNI_FALSE; /* print but continue */ static jboolean printUsage = JNI_FALSE; /* print and exit*/ static jboolean printXUsage = JNI_FALSE; /* print and exit*/ +static char *showSettings = NULL; /* print but continue */ static const char *_program_name; static const char *_launcher_name; @@ -109,6 +110,7 @@ static void PrintJavaVersion(JNIEnv *env, jboolean extraLF); static void PrintUsage(JNIEnv* env, jboolean doXUsage); +static void ShowSettings(JNIEnv* env, char *optString); static void SetPaths(int argc, char **argv); @@ -157,6 +159,7 @@ * create a new thread to invoke JVM. See 6316197 for more information. */ static jlong threadStackSize = 0; /* stack size of the new thread */ +static jlong heapSize = 0; /* heap size */ int JNICALL JavaMain(void * args); /* entry point */ @@ -376,6 +379,10 @@ } } + if (showSettings != NULL) { + ShowSettings(env, showSettings); + CHECK_EXCEPTION_LEAVE(0); + } /* If the user specified neither a class name nor a JAR file */ if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) { PrintUsage(env, printXUsage); @@ -611,7 +618,7 @@ /* copied from HotSpot function "atomll()" */ static int -parse_stack_size(const char *s, jlong *result) { +parse_size(const char *s, jlong *result) { jlong n = 0; int args_read = sscanf(s, jlong_format_specifier(), &n); if (args_read != 1) { @@ -673,10 +680,17 @@ options[numOptions++].extraInfo = info; if (JLI_StrCCmp(str, "-Xss") == 0) { - jlong tmp; - if (parse_stack_size(str + 4, &tmp)) { - threadStackSize = tmp; - } + jlong tmp; + if (parse_size(str + 4, &tmp)) { + threadStackSize = tmp; + } + } + + if (JLI_StrCCmp(str, "-Xmx") == 0) { + jlong tmp; + if (parse_size(str + 4, &tmp)) { + heapSize = tmp; + } } } @@ -1015,6 +1029,13 @@ printXUsage = JNI_TRUE; return JNI_TRUE; /* + * The following case checks for -XshowSettings OR -XshowSetting:SUBOPT. + * In the latter case, any SUBOPT value not recognized will default to "all" + */ + } else if (JLI_StrCmp(arg, "-XshowSettings") == 0 || + JLI_StrCCmp(arg, "-XshowSettings:") == 0) { + showSettings = arg; +/* * The following case provide backward compatibility with old-style * command line options. */ @@ -1475,6 +1496,27 @@ } /* + * Prints all the Java settings, see the java implementation for more details. + */ +static void +ShowSettings(JNIEnv *env, char *optString) +{ + jclass cls; + jmethodID showSettingsID; + jstring joptString; + NULL_CHECK(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper")); + NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls, + "showSettings", "(ZLjava/lang/String;JJZ)V")); + joptString = (*env)->NewStringUTF(env, optString); + (*env)->CallStaticVoidMethod(env, cls, showSettingsID, + JNI_TRUE, + joptString, + (jlong)heapSize, + (jlong)threadStackSize, + ServerClassMachine()); +} + +/* * Prints default usage or the Xusage message, see sun.launcher.LauncherHelper.java */ static void diff -r fa827ef8c75e -r 906c58a8b849 jdk/src/share/classes/sun/launcher/LauncherHelper.java --- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java Wed Nov 24 07:43:06 2010 +0800 +++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java Tue Nov 23 16:52:39 2010 -0800 @@ -44,8 +44,16 @@ import java.io.PrintStream; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; import java.util.ResourceBundle; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Properties; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; @@ -59,6 +67,17 @@ private static StringBuilder outBuf = new StringBuilder(); private static ResourceBundle javarb = null; + + private static final String INDENT = " "; + private static final String VM_SETTINGS = "VM settings:"; + private static final String PROP_SETTINGS = "Property settings:"; + private static final String LOCALE_SETTINGS = "Locale settings:"; + + private static final long K = 1024; + private static final long M = K * K; + private static final long G = M * K; + private static final long T = G * K; + private static synchronized ResourceBundle getLauncherResourceBundle() { if (javarb == null) { javarb = ResourceBundle.getBundle(defaultBundleName); @@ -66,6 +85,184 @@ return javarb; } + /* + * A method called by the launcher to print out the standard settings, + * by default -XshowSettings is equivalent to -XshowSettings:all, + * Specific information may be gotten by using suboptions with possible + * values vm, properties and locale. + * + * printToStderr: choose between stdout and stderr + * + * optionFlag: specifies which options to print default is all other + * possible values are vm, properties, locale. + * + * maxHeapSize: in bytes, as set by the launcher, a zero-value indicates + * this code should determine this value, using a suitable method. + * + * stackSize: in bytes, as set by the launcher, a zero-value indicates + * this code determine this value, using a suitable method. + */ + static void showSettings(boolean printToStderr, String optionFlag, + long maxHeapSize, long stackSize, boolean isServer) { + + PrintStream ostream = (printToStderr) ? System.err : System.out; + String opts[] = optionFlag.split(":"); + String optStr = (opts.length > 1 && opts[1] != null) + ? opts[1].trim() + : "all"; + switch (optStr) { + case "vm": + printVmSettings(ostream, maxHeapSize, stackSize, isServer); + break; + case "properties": + printProperties(ostream); + break; + case "locale": + printLocale(ostream); + break; + default: + printVmSettings(ostream, maxHeapSize, stackSize, isServer); + printProperties(ostream); + printLocale(ostream); + break; + } + } + + /* + * prints the main vm settings subopt/section + */ + private static void printVmSettings(PrintStream ostream, long maxHeapSize, + long stackSize, boolean isServer) { + + ostream.println(VM_SETTINGS); + if (stackSize != 0L) { + ostream.println(INDENT + "Stack Size: " + scaleValue(stackSize)); + } + if (maxHeapSize != 0L) { + ostream.println(INDENT + "Max. Heap Size: " + scaleValue(maxHeapSize)); + } else { + ostream.println(INDENT + "Max. Heap Size (Estimated): " + + scaleValue(Runtime.getRuntime().maxMemory())); + } + ostream.println(INDENT + "Ergonomics Machine Class: " + + ((isServer) ? "server" : "client")); + ostream.println(INDENT + "Using VM: " + + System.getProperty("java.vm.name")); + ostream.println(); + } + + /* + * scale the incoming values to a human readable form, represented as + * K, M, G and T, see java.c parse_size for the scaled values and + * suffixes. + */ + + private static String scaleValue(double v) { + MathContext mc2 = new MathContext(3, RoundingMode.HALF_EVEN); + + if (v >= K && v < M) { + return (new BigDecimal(v / K, mc2)).toPlainString() + "K"; + } else if (v >= M && v < G) { + return (new BigDecimal(v / M, mc2)).toPlainString() + "M"; + } else if (v >= G && v < T) { + return (new BigDecimal(v / G, mc2)).toPlainString() + "G"; + } else if (v >= T) { + return (new BigDecimal(v / T, mc2)).toPlainString() + "T"; + } else { + return String.format("%.0f", v); + } + } + + /* + * prints the properties subopt/section + */ + private static void printProperties(PrintStream ostream) { + Properties p = System.getProperties(); + ostream.println(PROP_SETTINGS); + List sortedPropertyKeys = new ArrayList<>(); + sortedPropertyKeys.addAll(p.stringPropertyNames()); + Collections.sort(sortedPropertyKeys); + for (String x : sortedPropertyKeys) { + printPropertyValue(ostream, x, p.getProperty(x)); + } + ostream.println(); + } + + private static boolean isPath(String key) { + return key.endsWith(".dirs") || key.endsWith(".path"); + } + + private static void printPropertyValue(PrintStream ostream, + String key, String value) { + ostream.print(INDENT + key + " = "); + if (key.equals("line.separator")) { + byte[] bytes = value.getBytes(); + for (byte b : bytes) { + switch (b) { + case 0xd: + ostream.print("CR "); + break; + case 0xa: + ostream.print("LF "); + break; + default: + ostream.printf("0x%02X", b & 0xff); + break; + } + } + ostream.println(); + return; + } + if (!isPath(key)) { + ostream.println(value); + return; + } + // pretty print the path values as a list + String[] values = value.split(System.getProperty("path.separator")); + int len = values.length; + for (int i = 0 ; i < len ; i++) { + if (i == 0) { // first line treated specially + ostream.println(values[i]); + } else { // following lines prefix with indents + ostream.print(INDENT + INDENT); + ostream.println(values[i]); + } + } + } + + /* + * prints the locale subopt/section + */ + private static void printLocale(PrintStream ostream) { + Locale locale = Locale.getDefault(); + ostream.println(LOCALE_SETTINGS); + ostream.println(INDENT + "default locale = " + locale.getDisplayLanguage()); + printLocales(ostream); + ostream.println(); + } + + private static void printLocales(PrintStream ostream) { + Locale[] locales = Locale.getAvailableLocales(); + final int len = locales == null ? 0 : locales.length; + if (len < 1 ) { + return; + } + ostream.print(INDENT + "available locales = "); + final int last = len - 1 ; + for (int i = 0; i < last ; i++) { + ostream.print(locales[i]); + if (i != last) { + ostream.print(", "); + } + // print columns of 8 + if ((i + 1) % 8 == 0) { + ostream.println(); + ostream.print(INDENT + INDENT); + } + } + ostream.println(locales[last]); + } + /** * A private helper method to get a localized message and also * apply any arguments that we might pass. diff -r fa827ef8c75e -r 906c58a8b849 jdk/src/share/classes/sun/launcher/resources/launcher.properties --- a/jdk/src/share/classes/sun/launcher/resources/launcher.properties Wed Nov 24 07:43:06 2010 +0800 +++ b/jdk/src/share/classes/sun/launcher/resources/launcher.properties Tue Nov 23 16:52:39 2010 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -97,7 +97,15 @@ \ -Xcheck:jni perform additional checks for JNI functions\n\ \ -Xshare:off do not attempt to use shared class data\n\ \ -Xshare:auto use shared class data if possible (default)\n\ -\ -Xshare:on require using shared class data, otherwise fail.\n\n\ +\ -Xshare:on require using shared class data, otherwise fail.\n\ +\ -XshowSettings show all settings and continue\n\ +\ -XshowSettings:all\n\ +\ show all settings and continue\n\ +\ -XshowSettings:vm show all vm related settings and continue\n\ +\ -XshowSettings:properties\n\ +\ show all property settings and continue\n\ +\ -XshowSettings:locale\n\ +\ show all locale related settings and continue\n\n\ The -X options are non-standard and subject to change without notice.\n java.launcher.cls.error1=\ diff -r fa827ef8c75e -r 906c58a8b849 jdk/test/tools/launcher/Settings.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/launcher/Settings.java Tue Nov 23 16:52:39 2010 -0800 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.io.File; +import java.io.IOException; + +/* + * @test + * @bug 6994753 + * @summary tests -XshowSettings options + * @compile -XDignore.symbol.file Settings.java TestHelper.java + * @run main Settings + * @author ksrini + */ +public class Settings { + private static File testJar = null; + + static void init() throws IOException { + if (testJar != null) { + return; + } + testJar = new File("test.jar"); + StringBuilder tsrc = new StringBuilder(); + tsrc.append("public static void main(String... args) {\n"); + tsrc.append(" for (String x : args) {\n"); + tsrc.append(" System.out.println(x);\n"); + tsrc.append(" }\n"); + tsrc.append("}\n"); + TestHelper.createJar(testJar, tsrc.toString()); + } + + static void checkContains(TestHelper.TestResult tr, String str) { + if (!tr.contains(str)) { + System.out.println(tr); + throw new RuntimeException(str + " not found"); + } + } + + static void checkNoContains(TestHelper.TestResult tr, String str) { + if (tr.contains(str)) { + System.out.println(tr.status); + throw new RuntimeException(str + " found"); + } + } + + private static final String VM_SETTINGS = "VM settings:"; + private static final String PROP_SETTINGS = "Property settings:"; + private static final String LOCALE_SETTINGS = "Locale settings:"; + + static void containsAllOptions(TestHelper.TestResult tr) { + checkContains(tr, VM_SETTINGS); + checkContains(tr, PROP_SETTINGS); + checkContains(tr, LOCALE_SETTINGS); + } + + static void runTestOptionDefault() throws IOException { + TestHelper.TestResult tr = null; + tr = TestHelper.doExec(TestHelper.javaCmd, "-Xmx512m", "-Xss128k", + "-XshowSettings", "-jar", testJar.getAbsolutePath()); + containsAllOptions(tr); + if (!tr.isOK()) { + System.out.println(tr.status); + throw new RuntimeException("test fails"); + } + } + + static void runTestOptionAll() throws IOException { + init(); + TestHelper.TestResult tr = null; + tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:all"); + containsAllOptions(tr); + } + + static void runTestOptionVM() throws IOException { + TestHelper.TestResult tr = null; + tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:vm"); + checkContains(tr, VM_SETTINGS); + checkNoContains(tr, PROP_SETTINGS); + checkNoContains(tr, LOCALE_SETTINGS); + } + + static void runTestOptionProperty() throws IOException { + TestHelper.TestResult tr = null; + tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:properties"); + checkNoContains(tr, VM_SETTINGS); + checkContains(tr, PROP_SETTINGS); + checkNoContains(tr, LOCALE_SETTINGS); + } + + static void runTestOptionLocale() throws IOException { + TestHelper.TestResult tr = null; + tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:locale"); + checkNoContains(tr, VM_SETTINGS); + checkNoContains(tr, PROP_SETTINGS); + checkContains(tr, LOCALE_SETTINGS); + } + + static void runTestBadOptions() throws IOException { + TestHelper.TestResult tr = null; + tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettingsBadOption"); + checkNoContains(tr, VM_SETTINGS); + checkNoContains(tr, PROP_SETTINGS); + checkNoContains(tr, LOCALE_SETTINGS); + checkContains(tr, "Unrecognized option: -XshowSettingsBadOption"); + } + public static void main(String... args) { + try { + runTestOptionAll(); + runTestOptionDefault(); + runTestOptionVM(); + runTestOptionProperty(); + runTestOptionLocale(); + runTestBadOptions(); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } +}