6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
Reviewed-by: dholmes
--- a/jdk/src/share/classes/java/util/logging/LogRecord.java Fri Oct 22 17:40:31 2010 +0100
+++ b/jdk/src/share/classes/java/util/logging/LogRecord.java Fri Oct 22 11:22:54 2010 -0700
@@ -529,8 +529,6 @@
Throwable throwable = new Throwable();
int depth = access.getStackTraceDepth(throwable);
- String logClassName = "java.util.logging.Logger";
- String plogClassName = "sun.util.logging.PlatformLogger";
boolean lookingForLogger = true;
for (int ix = 0; ix < depth; ix++) {
// Calling getStackTraceElement directly prevents the VM
@@ -538,13 +536,14 @@
StackTraceElement frame =
access.getStackTraceElement(throwable, ix);
String cname = frame.getClassName();
+ boolean isLoggerImpl = isLoggerImplFrame(cname);
if (lookingForLogger) {
// Skip all frames until we have found the first logger frame.
- if (cname.equals(logClassName) || cname.startsWith(plogClassName)) {
+ if (isLoggerImpl) {
lookingForLogger = false;
}
} else {
- if (!cname.equals(logClassName) && !cname.startsWith(plogClassName)) {
+ if (!isLoggerImpl) {
// skip reflection call
if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) {
// We've found the relevant frame.
@@ -558,4 +557,11 @@
// We haven't found a suitable frame, so just punt. This is
// OK as we are only committed to making a "best effort" here.
}
+
+ private boolean isLoggerImplFrame(String cname) {
+ // the log record could be created for a platform logger
+ return (cname.equals("java.util.logging.Logger") ||
+ cname.startsWith("java.util.logging.LoggingProxyImpl") ||
+ cname.startsWith("sun.util.logging."));
+ }
}
--- a/jdk/src/share/classes/sun/util/logging/PlatformLogger.java Fri Oct 22 17:40:31 2010 +0100
+++ b/jdk/src/share/classes/sun/util/logging/PlatformLogger.java Fri Oct 22 11:22:54 2010 -0700
@@ -535,10 +535,6 @@
}
void doLog(int level, String msg, Object... params) {
- int paramsNumber = (params != null) ? params.length : 0;
- for (int i = 0; i < paramsNumber; i++) {
- params[i] = String.valueOf(params[i]);
- }
LoggingSupport.log(javaLogger, levelObjects.get(level), msg, params);
}
--- a/jdk/test/sun/util/logging/PlatformLoggerTest.java Fri Oct 22 17:40:31 2010 +0100
+++ b/jdk/test/sun/util/logging/PlatformLoggerTest.java Fri Oct 22 11:22:54 2010 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6882376
+ * @bug 6882376 6985460
* @summary Test if java.util.logging.Logger is created before and after
* logging is enabled. Also validate some basic PlatformLogger
* operations.
@@ -43,6 +43,8 @@
final String GOO_PLATFORM_LOGGER = "test.platformlogger.goo";
final String BAR_LOGGER = "test.logger.bar";
PlatformLogger goo = PlatformLogger.getLogger(GOO_PLATFORM_LOGGER);
+ // test the PlatformLogger methods
+ testLogMethods(goo);
// Create a platform logger using the default
PlatformLogger foo = PlatformLogger.getLogger(FOO_PLATFORM_LOGGER);
@@ -56,6 +58,10 @@
PlatformLogger bar = PlatformLogger.getLogger(BAR_PLATFORM_LOGGER);
checkPlatformLogger(bar, BAR_PLATFORM_LOGGER);
+ // test the PlatformLogger methods
+ testLogMethods(goo);
+ testLogMethods(bar);
+
checkLogger(FOO_PLATFORM_LOGGER, Level.FINER);
checkLogger(BAR_PLATFORM_LOGGER, Level.FINER);
@@ -64,6 +70,7 @@
foo.setLevel(PlatformLogger.SEVERE);
checkLogger(FOO_PLATFORM_LOGGER, Level.SEVERE);
+
}
private static void checkPlatformLogger(PlatformLogger logger, String name) {
@@ -108,4 +115,33 @@
logger.getName() + " " + logger.getLevel());
}
}
+
+ private static void testLogMethods(PlatformLogger logger) {
+ logger.severe("Test severe(String, Object...) {0} {1}", new Long(1), "string");
+ // test Object[]
+ logger.severe("Test severe(String, Object...) {0}", (Object[]) getPoints());
+ logger.warning("Test warning(String, Throwable)", new Throwable("Testing"));
+ logger.info("Test info(String)");
+ }
+
+ static Point[] getPoints() {
+ Point[] res = new Point[3];
+ res[0] = new Point(0,0);
+ res[1] = new Point(1,1);
+ res[2] = new Point(2,2);
+ return res;
+ }
+
+ static class Point {
+ final int x;
+ final int y;
+ public Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+ public String toString() {
+ return "{x="+x + ", y=" + y + "}";
+ }
+ }
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/util/logging/SourceClassName.java Fri Oct 22 11:22:54 2010 -0700
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 6985460
+ * @summary Test the source class name and method output by the platform
+ * logger.
+ *
+ * @compile -XDignore.symbol.file SourceClassName.java
+ * @run main/othervm SourceClassName
+ */
+
+import java.util.logging.*;
+import java.io.*;
+import sun.util.logging.PlatformLogger;
+
+public class SourceClassName {
+ public static void main(String[] args) throws Exception {
+ File dir = new File(System.getProperty("user.dir", "."));
+ File log = new File(dir, "testlog.txt");
+ PrintStream logps = new PrintStream(log);
+ writeLogRecords(logps);
+ checkLogRecords(log);
+ }
+
+ private static void writeLogRecords(PrintStream logps) throws Exception {
+ PrintStream err = System.err;
+ try {
+ System.setErr(logps);
+
+ Object[] params = new Object[] { new Long(1), "string"};
+ PlatformLogger plog = PlatformLogger.getLogger("test.log.foo");
+ plog.severe("Log message {0} {1}", (Object[]) params);
+
+ // create a java.util.logging.Logger
+ // now java.util.logging.Logger should be created for each platform logger
+ Logger logger = Logger.getLogger("test.log.bar");
+ logger.log(Level.SEVERE, "Log message {0} {1}", params);
+
+ plog.severe("Log message {0} {1}", (Object[]) params);
+ } finally {
+ logps.flush();
+ logps.close();
+ System.setErr(err);
+ }
+ }
+
+ private static void checkLogRecords(File log) throws Exception {
+ System.out.println("Checking log records in file: " + log);
+ FileInputStream in = new FileInputStream(log);
+ String EXPECTED_LOG = "SEVERE: Log message 1 string";
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ String line;
+ String[] record = new String[2];
+ int count = 0;
+ int i = 0;
+ while ((line = reader.readLine()) != null) {
+ line = line.trim();
+ System.out.println(line);
+ record[i++] = line;
+ if (i == 2) {
+ i = 0;
+ count++;
+ // check source class name and method
+ String[] ss = record[0].split("\\s+");
+ int len = ss.length;
+ if (!ss[len-2].equals("SourceClassName") ||
+ !ss[len-1].equals("writeLogRecords")) {
+ throw new RuntimeException("Unexpected source: " +
+ ss[len-2] + " " + ss[len-1]);
+ }
+
+ // check log message
+ if (!record[1].equals(EXPECTED_LOG)) {
+ throw new RuntimeException("Unexpected log: " + record[1]);
+ }
+ }
+ }
+ if (count != 3) {
+ throw new RuntimeException("Unexpected number of records: " + count);
+ }
+ } finally {
+ in.close();
+ }
+ }
+}