6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
authormchung
Fri, 22 Oct 2010 11:22:54 -0700
changeset 7026 9f2ec5fad124
parent 7025 6e002f9a2899
child 7027 d3404b1406d5
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized Reviewed-by: dholmes
jdk/src/share/classes/java/util/logging/LogRecord.java
jdk/src/share/classes/sun/util/logging/PlatformLogger.java
jdk/test/sun/util/logging/PlatformLoggerTest.java
jdk/test/sun/util/logging/SourceClassName.java
--- 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();
+        }
+    }
+}