6876135: Add PlatformLoggingMXBean to eliminate the dependency on JMX from logging
authormchung
Tue, 27 Oct 2009 16:32:23 -0700
changeset 4172 bceea7bc12b7
parent 4171 7edb512fdaa6
child 4173 d01972926813
6876135: Add PlatformLoggingMXBean to eliminate the dependency on JMX from logging Summary: Added a new PlatformLoggingMXBean interface to extend PlatformManagedObject instead of LoggingMXBean Reviewed-by: alanb
jdk/src/share/classes/java/lang/management/PlatformComponent.java
jdk/src/share/classes/java/util/logging/LogManager.java
jdk/src/share/classes/java/util/logging/Logging.java
jdk/src/share/classes/java/util/logging/LoggingMXBean.java
jdk/src/share/classes/java/util/logging/LoggingProxyImpl.java
jdk/src/share/classes/java/util/logging/PlatformLoggingMXBean.java
jdk/src/share/classes/sun/management/ManagementFactoryHelper.java
jdk/src/share/classes/sun/util/logging/LoggingProxy.java
jdk/src/share/classes/sun/util/logging/LoggingSupport.java
jdk/src/share/classes/sun/util/logging/PlatformLogger.java
jdk/test/java/util/logging/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java
--- a/jdk/src/share/classes/java/lang/management/PlatformComponent.java	Tue Oct 27 16:31:01 2009 -0700
+++ b/jdk/src/share/classes/java/lang/management/PlatformComponent.java	Tue Oct 27 16:32:23 2009 -0700
@@ -30,8 +30,7 @@
 import java.util.List;
 import java.util.HashSet;
 import java.util.Set;
-import java.util.logging.LoggingMXBean;
-import java.util.logging.LogManager;
+import java.util.logging.PlatformLoggingMXBean;
 import java.nio.BufferPoolMXBean;
 import javax.management.MBeanServerConnection;
 import javax.management.ObjectName;
@@ -181,15 +180,14 @@
      * Logging facility.
      */
     LOGGING(
-        "java.util.logging.LoggingMXBean",
+        "java.util.logging.PlatformLoggingMXBean",
         "java.util.logging", "Logging", defaultKeyProperties(),
-        new MXBeanFetcher<LoggingMXBean>() {
-            public List<LoggingMXBean> getMXBeans() {
-                return Collections.singletonList(LogManager.getLoggingMXBean());
+        new MXBeanFetcher<PlatformLoggingMXBean>() {
+            public List<PlatformLoggingMXBean> getMXBeans() {
+                return ManagementFactoryHelper.getLoggingMXBean();
             }
         }),
 
-
     /**
      * Buffer pools.
      */
--- a/jdk/src/share/classes/java/util/logging/LogManager.java	Tue Oct 27 16:31:01 2009 -0700
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java	Tue Oct 27 16:32:23 2009 -0700
@@ -1039,12 +1039,16 @@
 
     /**
      * Returns <tt>LoggingMXBean</tt> for managing loggers.
-     * The <tt>LoggingMXBean</tt> can also obtained from the
-     * {@link java.lang.management.ManagementFactory#getPlatformMBeanServer
-     * platform <tt>MBeanServer</tt>} method.
+     * An alternative way to manage loggers is using
+     * the {@link java.lang.management.ManagementFactory#getPlatformMXBeans(Class)
+     * ManagementFactory.getPlatformMXBeans} method as follows:
+     * <pre>
+     *     List&lt{@link PlatformLoggingMXBean}&gt result = ManagementFactory.getPlatformMXBeans(PlatformLoggingMXBean.class);
+     * </pre>
      *
      * @return a {@link LoggingMXBean} object.
      *
+     * @see PlatformLoggingMXBean
      * @see java.lang.management.ManagementFactory
      * @since 1.5
      */
--- a/jdk/src/share/classes/java/util/logging/Logging.java	Tue Oct 27 16:31:01 2009 -0700
+++ b/jdk/src/share/classes/java/util/logging/Logging.java	Tue Oct 27 16:32:23 2009 -0700
@@ -29,9 +29,6 @@
 import java.util.List;
 import java.util.ArrayList;
 
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
 /**
  * Logging is the implementation class of LoggingMXBean.
  *
@@ -117,12 +114,4 @@
             return p.getName();
         }
     }
-
-    public ObjectName getObjectName() {
-        try {
-            return ObjectName.getInstance(LogManager.LOGGING_MXBEAN_NAME);
-        } catch (MalformedObjectNameException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
 }
--- a/jdk/src/share/classes/java/util/logging/LoggingMXBean.java	Tue Oct 27 16:31:01 2009 -0700
+++ b/jdk/src/share/classes/java/util/logging/LoggingMXBean.java	Tue Oct 27 16:32:23 2009 -0700
@@ -25,7 +25,6 @@
 
 package java.util.logging;
 
-import java.lang.management.PlatformManagedObject;
 
 /**
  * The management interface for the logging facility.
@@ -35,27 +34,26 @@
  * <a href="../../lang/management/ManagementFactory.html#MXBean">MXBean</a>
  * can be obtained by calling
  * the {@link LogManager#getLoggingMXBean} method or from the
- * {@link java.lang.management.ManagementFactory#getPlatformMBeanServer
- * platform <tt>MBeanServer</tt>} method.
+ * {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer
+ * platform <tt>MBeanServer</tt>}.
  *
- * <p>The {@link javax.management.ObjectName ObjectName} for uniquely
+ * The {@link javax.management.ObjectName ObjectName} for uniquely
  * identifying the <tt>LoggingMXBean</tt> within an MBeanServer is:
  * <blockquote>
  *    {@link LogManager#LOGGING_MXBEAN_NAME
  *           <tt>java.util.logging:type=Logging</tt>}
  * </blockquote>
  *
- * It can be obtained by calling the
- * {@link PlatformManagedObject#getObjectName} method.
- *
- * @see java.lang.management.ManagementFactory#getPlatformMXBeans(Class)
+ * The instance registered in the platform <tt>MBeanServer</tt> with
+ * this {@code ObjectName} is also a {@link PlatformLoggingMXBean}.
  *
  * @author  Ron Mann
  * @author  Mandy Chung
  * @since   1.5
  *
+ * @see PlatformLoggingMXBean
  */
-public interface LoggingMXBean extends PlatformManagedObject {
+public interface LoggingMXBean {
 
     /**
      * Returns the list of currently registered loggers. This method
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/logging/LoggingProxyImpl.java	Tue Oct 27 16:32:23 2009 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.util.logging;
+
+import sun.util.logging.LoggingProxy;
+
+/**
+ * Implementation of LoggingProxy when java.util.logging classes exist.
+ */
+class LoggingProxyImpl implements LoggingProxy {
+    static final LoggingProxy INSTANCE = new LoggingProxyImpl();
+
+    private LoggingProxyImpl() { }
+
+    @Override
+    public Object getLogger(String name) {
+        return Logger.getLogger(name);
+    }
+
+    @Override
+    public Object getLevel(Object logger) {
+        return ((Logger) logger).getLevel();
+    }
+
+    @Override
+    public void setLevel(Object logger, Object newLevel) {
+        ((Logger) logger).setLevel((Level) newLevel);
+    }
+
+    @Override
+    public boolean isLoggable(Object logger, Object level) {
+        return ((Logger) logger).isLoggable((Level) level);
+    }
+
+    @Override
+    public void log(Object logger, Object level, String msg) {
+        ((Logger) logger).log((Level) level, msg);
+    }
+
+    @Override
+    public void log(Object logger, Object level, String msg, Throwable t) {
+        ((Logger) logger).log((Level) level, msg, t);
+    }
+
+    @Override
+    public void log(Object logger, Object level, String msg, Object... params) {
+        ((Logger) logger).log((Level) level, msg, params);
+    }
+
+    @Override
+    public java.util.List<String> getLoggerNames() {
+        return LogManager.getLoggingMXBean().getLoggerNames();
+    }
+
+    @Override
+    public String getLoggerLevel(String loggerName) {
+        return LogManager.getLoggingMXBean().getLoggerLevel(loggerName);
+    }
+
+    @Override
+    public void setLoggerLevel(String loggerName, String levelName) {
+        LogManager.getLoggingMXBean().setLoggerLevel(loggerName, levelName);
+    }
+
+    @Override
+    public String getParentLoggerName(String loggerName) {
+        return LogManager.getLoggingMXBean().getParentLoggerName(loggerName);
+    }
+
+    @Override
+    public Object parseLevel(String levelName) {
+        return Level.parse(levelName);
+    }
+
+    @Override
+    public String getLevelName(Object level) {
+        return ((Level) level).getName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/logging/PlatformLoggingMXBean.java	Tue Oct 27 16:32:23 2009 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.util.logging;
+
+import java.lang.management.PlatformManagedObject;
+
+/**
+ * The {@linkplain PlatformManagedObject platform managed object} for the
+ * logging facility.  This interface simply unifies {@link LoggingMXBean}
+ * {@link PlatformManagedObject};
+ * and it does not specify any new operations.
+ *
+ * <p>The {@link java.lang.management.ManagementFactory#getPlatformMXBeans(Class)
+ * ManagementFactory.getPlatformMXBeans} method can be used to obtain
+ * the {@code PlatformLoggingMXBean} object as follows:
+ * <pre>
+ *     ManagementFactory.getPlatformMXBeans(PlatformLoggingMXBean.class);
+ * </pre>
+ * or from the {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer
+ * platform <tt>MBeanServer</tt>}.
+ *
+ * The {@link javax.management.ObjectName ObjectName} for uniquely
+ * identifying the <tt>LoggingMXBean</tt> within an MBeanServer is:
+ * <blockquote>
+ *           <tt>java.util.logging:type=Logging</tt>
+ * </blockquote>
+ *
+ * The {@link PlatformManagedObject#getObjectName} method
+ * can be used to obtain its {@code ObjectName}.
+ *
+ * @See java.lang.management.PlatformManagedObject
+ *
+ * @author  Mandy Chung
+ * @since   1.7
+ */
+public interface PlatformLoggingMXBean extends LoggingMXBean, PlatformManagedObject {
+}
--- a/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java	Tue Oct 27 16:31:01 2009 -0700
+++ b/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java	Tue Oct 27 16:32:23 2009 -0700
@@ -40,7 +40,11 @@
 import java.security.PrivilegedExceptionAction;
 import sun.security.action.LoadLibraryAction;
 
+import java.util.logging.PlatformLoggingMXBean;
+import sun.util.logging.LoggingSupport;
+
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import com.sun.management.OSMBeanFactory;
 import com.sun.management.HotSpotDiagnosticMXBean;
@@ -135,6 +139,54 @@
         return result;
     }
 
+    public static List<PlatformLoggingMXBean> getLoggingMXBean() {
+        if (LoggingSupport.isAvailable()) {
+            return Collections.singletonList(createPlatformLoggingMXBean());
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    private final static String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
+    private static PlatformLoggingMXBean createPlatformLoggingMXBean() {
+        return new PlatformLoggingMXBean() {
+            private volatile ObjectName objname;  // created lazily
+            @Override
+            public ObjectName getObjectName() {
+                ObjectName result = objname;
+                if (result == null) {
+                    synchronized (this) {
+                        if (objname == null) {
+                            result = Util.newObjectName(LOGGING_MXBEAN_NAME);
+                            objname = result;
+                        }
+                    }
+                }
+                return result;
+            }
+
+            @Override
+            public java.util.List<String> getLoggerNames() {
+                return LoggingSupport.getLoggerNames();
+            }
+
+            @Override
+            public String getLoggerLevel(String loggerName) {
+                return LoggingSupport.getLoggerLevel(loggerName);
+            }
+
+            @Override
+            public void setLoggerLevel(String loggerName, String levelName) {
+                LoggingSupport.setLoggerLevel(loggerName, levelName);
+            }
+
+            @Override
+            public String getParentLoggerName(String loggerName) {
+                return LoggingSupport.getParentLoggerName(loggerName);
+            }
+        };
+    }
+
     public static List<BufferPoolMXBean> getBufferPoolMXBeans() {
         List<BufferPoolMXBean> pools = new ArrayList<BufferPoolMXBean>(2);
         pools.add(createBufferPoolMXBean(sun.misc.SharedSecrets.getJavaNioAccess()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/util/logging/LoggingProxy.java	Tue Oct 27 16:32:23 2009 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+package sun.util.logging;
+
+/**
+ * A proxy interface for the java.util.logging support.
+ *
+ * @see sun.util.logging.LoggingSupport
+ */
+public interface LoggingProxy {
+    // Methods to bridge java.util.logging.Logger methods
+    public Object getLogger(String name);
+
+    public Object getLevel(Object logger);
+
+    public void setLevel(Object logger, Object newLevel);
+
+    public boolean isLoggable(Object logger, Object level);
+
+    public void log(Object logger, Object level, String msg);
+
+    public void log(Object logger, Object level, String msg, Throwable t);
+
+    public void log(Object logger, Object level, String msg, Object... params);
+
+    // Methods to bridge java.util.logging.LoggingMXBean methods
+    public java.util.List<String> getLoggerNames();
+
+    public String getLoggerLevel(String loggerName);
+
+    public void setLoggerLevel(String loggerName, String levelName);
+
+    public String getParentLoggerName(String loggerName);
+
+    // Methods to bridge Level.parse() and Level.getName() method
+    public Object parseLevel(String levelName);
+
+    public String getLevelName(Object level);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/util/logging/LoggingSupport.java	Tue Oct 27 16:32:23 2009 -0700
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+package sun.util.logging;
+
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Internal API to support JRE implementation to detect if the java.util.logging
+ * support is available but with no dependency on the java.util.logging
+ * classes.  This LoggingSupport class provides several static methods to
+ * access the java.util.logging functionality that requires the caller
+ * to ensure that the logging support is {@linkplain #isAvailable available}
+ * before invoking it.
+ *
+ * @see sun.util.logging.PlatformLogger if you want to log messages even
+ * if the logging support is not available
+ */
+public class LoggingSupport {
+    private LoggingSupport() { }
+
+    private static final LoggingProxy proxy =
+        AccessController.doPrivileged(new PrivilegedAction<LoggingProxy>() {
+            public LoggingProxy run() {
+                try {
+                    // create a LoggingProxyImpl instance when
+                    // java.util.logging classes exist
+                    Class<?> c = Class.forName("java.util.logging.LoggingProxyImpl", true, null);
+                    Field f = c.getDeclaredField("INSTANCE");
+                    f.setAccessible(true);
+                    return (LoggingProxy) f.get(null);
+                } catch (ClassNotFoundException cnf) {
+                    return null;
+                } catch (NoSuchFieldException e) {
+                    throw new AssertionError(e);
+                } catch (IllegalAccessException e) {
+                    throw new AssertionError(e);
+                }
+            }});
+
+    /**
+     * Returns true if java.util.logging support is available.
+     */
+    public static boolean isAvailable() {
+        return proxy != null;
+    }
+
+    private static void ensureAvailable() {
+        if (proxy == null)
+            throw new AssertionError("Should not here");
+    }
+
+    public static java.util.List<String> getLoggerNames() {
+        ensureAvailable();
+        return proxy.getLoggerNames();
+    }
+    public static String getLoggerLevel(String loggerName) {
+        ensureAvailable();
+        return proxy.getLoggerLevel(loggerName);
+    }
+
+    public static void setLoggerLevel(String loggerName, String levelName) {
+        ensureAvailable();
+        proxy.setLoggerLevel(loggerName, levelName);
+    }
+
+    public static String getParentLoggerName(String loggerName) {
+        ensureAvailable();
+        return proxy.getParentLoggerName(loggerName);
+    }
+
+    public static Object getLogger(String name) {
+        ensureAvailable();
+        return proxy.getLogger(name);
+    }
+
+    public static Object getLevel(Object logger) {
+        ensureAvailable();
+        return proxy.getLevel(logger);
+    }
+
+    public static void setLevel(Object logger, Object newLevel) {
+        ensureAvailable();
+        proxy.setLevel(logger, newLevel);
+    }
+
+    public static boolean isLoggable(Object logger, Object level) {
+        ensureAvailable();
+        return proxy.isLoggable(logger,level);
+    }
+
+    public static void log(Object logger, Object level, String msg) {
+        ensureAvailable();
+        proxy.log(logger, level, msg);
+    }
+
+    public static void log(Object logger, Object level, String msg, Throwable t) {
+        ensureAvailable();
+        proxy.log(logger, level, msg, t);
+    }
+
+    public static void log(Object logger, Object level, String msg, Object... params) {
+        ensureAvailable();
+        proxy.log(logger, level, msg, params);
+    }
+
+    public static Object parseLevel(String levelName) {
+        ensureAvailable();
+        return proxy.parseLevel(levelName);
+    }
+
+    public static String getLevelName(Object level) {
+        ensureAvailable();
+        return proxy.getLevelName(level);
+    }
+}
--- a/jdk/src/share/classes/sun/util/logging/PlatformLogger.java	Tue Oct 27 16:31:01 2009 -0700
+++ b/jdk/src/share/classes/sun/util/logging/PlatformLogger.java	Tue Oct 27 16:32:23 2009 -0700
@@ -136,7 +136,7 @@
      * This method is called from LogManager.readPrimordialConfiguration().
      */
     public static synchronized void redirectPlatformLoggers() {
-        if (loggingEnabled || !JavaLogger.supported) return;
+        if (loggingEnabled || !LoggingSupport.isAvailable()) return;
 
         loggingEnabled = true;
         for (Map.Entry<String, WeakReference<PlatformLogger>> entry : loggers.entrySet()) {
@@ -487,73 +487,22 @@
      * java.util.logging.Logger object.
      */
     static class JavaLogger extends LoggerProxy {
-        private static final boolean supported;
-        private static final Class<?> loggerClass;
-        private static final Class<?> levelClass;
-        private static final Method getLoggerMethod;
-        private static final Method setLevelMethod;
-        private static final Method getLevelMethod;
-        private static final Method isLoggableMethod;
-        private static final Method logMethod;
-        private static final Method logThrowMethod;
-        private static final Method logParamsMethod;
         private static final Map<Integer, Object> levelObjects =
             new HashMap<Integer, Object>();
 
         static {
-            loggerClass = getClass("java.util.logging.Logger");
-            levelClass = getClass("java.util.logging.Level");
-            getLoggerMethod = getMethod(loggerClass, "getLogger", String.class);
-            setLevelMethod = getMethod(loggerClass, "setLevel", levelClass);
-            getLevelMethod = getMethod(loggerClass, "getLevel");
-            isLoggableMethod = getMethod(loggerClass, "isLoggable", levelClass);
-            logMethod = getMethod(loggerClass, "log", levelClass, String.class);
-            logThrowMethod = getMethod(loggerClass, "log", levelClass, String.class, Throwable.class);
-            logParamsMethod = getMethod(loggerClass, "log", levelClass, String.class, Object[].class);
-            supported = (loggerClass != null && levelClass != null && getLoggerMethod != null &&
-                         getLevelMethod != null && setLevelMethod != null &&
-                         logMethod != null && logThrowMethod != null && logParamsMethod != null);
-            if (supported) {
+            if (LoggingSupport.isAvailable()) {
                 // initialize the map to Level objects
                 getLevelObjects();
             }
         }
 
-        private static Class<?> getClass(String name) {
-            try {
-                return Class.forName(name, true, null);
-            } catch (ClassNotFoundException e) {
-                return null;
-            }
-        }
-
-        private static Method getMethod(Class<?> cls, String name, Class<?>... parameterTypes) {
-            if (cls == null) return null;
-
-            try {
-                return cls.getMethod(name, parameterTypes);
-            } catch (NoSuchMethodException e) {
-                throw new AssertionError(e);
-            }
-        }
-
-        private static Object invoke(Method m, Object obj, Object... params) {
-            try {
-                return m.invoke(obj, params);
-            } catch (IllegalAccessException e) {
-                throw new AssertionError(e);
-            } catch (InvocationTargetException e) {
-                throw new AssertionError(e);
-            }
-        }
-
         private static void getLevelObjects() {
             // get all java.util.logging.Level objects
-            Method parseLevelMethod = getMethod(levelClass, "parse", String.class);
             int[] levelArray = new int[] {OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL};
             for (int l : levelArray) {
-                Object o = invoke(parseLevelMethod, null, getLevelName(l));
-                levelObjects.put(l, o);
+                Object level = LoggingSupport.parseLevel(getLevelName(l));
+                levelObjects.put(l, level);
             }
         }
 
@@ -564,10 +513,10 @@
 
         JavaLogger(String name, int level) {
             super(name, level);
-            this.javaLogger = invoke(getLoggerMethod, null, name);
+            this.javaLogger = LoggingSupport.getLogger(name);
             if (level != 0) {
                 // level has been updated and so set the Logger's level
-                invoke(setLevelMethod, javaLogger, levelObjects.get(level));
+                LoggingSupport.setLevel(javaLogger, levelObjects.get(level));
             }
         }
 
@@ -578,24 +527,24 @@
         * not be updated.
         */
         void doLog(int level, String msg) {
-            invoke(logMethod, javaLogger, levelObjects.get(level), msg);
+            LoggingSupport.log(javaLogger, levelObjects.get(level), msg);
         }
 
         void doLog(int level, String msg, Throwable t) {
-            invoke(logThrowMethod, javaLogger, levelObjects.get(level), msg, t);
+            LoggingSupport.log(javaLogger, levelObjects.get(level), msg, t);
         }
 
         void doLog(int level, String msg, Object... params) {
-            invoke(logParamsMethod, javaLogger, levelObjects.get(level), msg, params);
+            LoggingSupport.log(javaLogger, levelObjects.get(level), msg, params);
         }
 
         boolean isEnabled() {
-            Object level = invoke(getLevelMethod, javaLogger);
+            Object level = LoggingSupport.getLevel(javaLogger);
             return level == null || level.equals(levelObjects.get(OFF)) == false;
         }
 
         int getLevel() {
-            Object level = invoke(getLevelMethod, javaLogger);
+            Object level = LoggingSupport.getLevel(javaLogger);
             if (level != null) {
                 for (Map.Entry<Integer, Object> l : levelObjects.entrySet()) {
                     if (level == l.getValue()) {
@@ -608,15 +557,14 @@
 
         void setLevel(int newLevel) {
             levelValue = newLevel;
-            invoke(setLevelMethod, javaLogger, levelObjects.get(newLevel));
+            LoggingSupport.setLevel(javaLogger, levelObjects.get(newLevel));
         }
 
         public boolean isLoggable(int level) {
-            return (Boolean) invoke(isLoggableMethod, javaLogger, levelObjects.get(level));
+            return LoggingSupport.isLoggable(javaLogger, levelObjects.get(level));
         }
     }
 
-
     private static String getLevelName(int level) {
         switch (level) {
             case OFF     : return "OFF";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java	Tue Oct 27 16:32:23 2009 -0700
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     6876135
+ *
+ * @summary Test PlatformLoggingMXBean
+ *          This test performs similar testing as LoggingMXBeanTest.
+ *
+ * @build PlatformLoggingMXBeanTest
+ * @run main PlatformLoggingMXBeanTest
+ */
+
+import javax.management.*;
+import java.lang.management.ManagementFactory;
+import java.util.logging.*;
+import java.util.List;
+
+public class PlatformLoggingMXBeanTest
+{
+
+    ObjectName objectName = null;
+    static String LOGGER_NAME_1 = "com.sun.management.Logger1";
+    static String LOGGER_NAME_2 = "com.sun.management.Logger2";
+
+    public PlatformLoggingMXBeanTest() throws Exception {
+    }
+
+    private void runTest(PlatformLoggingMXBean mBean) throws Exception {
+
+        /*
+         * Create the MBeanServeri, register the PlatformLoggingMXBean
+         */
+        System.out.println( "***************************************************" );
+        System.out.println( "********** PlatformLoggingMXBean Unit Test **********" );
+        System.out.println( "***************************************************" );
+        System.out.println( "" );
+        System.out.println( "*******************************" );
+        System.out.println( "*********** Phase 1 ***********" );
+        System.out.println( "*******************************" );
+        System.out.println( "    Creating MBeanServer " );
+        System.out.print( "    Register PlatformLoggingMXBean: " );
+        MBeanServer mbs = MBeanServerFactory.createMBeanServer();
+        String[] list = new String[0];
+
+        try {
+            objectName = new ObjectName(LogManager.LOGGING_MXBEAN_NAME);
+            mbs.registerMBean( mBean, objectName );
+        }
+        catch ( Exception e ) {
+            System.out.println( "FAILED" );
+            throw e;
+        }
+        System.out.println( "PASSED" );
+        System.out.println("");
+
+        /*
+         * Access our MBean to get the current list of Loggers
+         */
+        System.out.println( "*******************************" );
+        System.out.println( "*********** Phase 2 ***********" );
+        System.out.println( "*******************************" );
+        System.out.println( "   Test Logger Name retrieval (getLoggerNames) " );
+        // check that Level object are returned properly
+        try {
+            list = (String[]) mbs.getAttribute( objectName,  "LoggerNames" );
+        }
+        catch ( Exception e ) {
+            System.out.println("    : FAILED" );
+            throw e;
+        }
+
+        /*
+         * Dump the list of Loggers already present, if any
+         */
+        Object[] params =  new Object[1];
+        String[] signature =  new String[1];
+        Level l;
+
+        if ( list == null ) {
+            System.out.println("    : PASSED.  No Standard Loggers Present" );
+            System.out.println("");
+        }
+        else {
+            System.out.println("    : PASSED. There are " + list.length + " Loggers Present" );
+            System.out.println("");
+            System.out.println( "*******************************" );
+            System.out.println( "*********** Phase 2B **********" );
+            System.out.println( "*******************************" );
+            System.out.println( " Examine Existing Loggers" );
+            for ( int i = 0; i < list.length; i++ ) {
+                try {
+                    params[0] = list[i];
+                    signature[0] = "java.lang.String";
+                    String levelName = (String) mbs.invoke(  objectName, "getLoggerLevel", params, signature );
+                    System.out.println("    : Logger #" + i + " = " + list[i] );
+                    System.out.println("    : Level = " + levelName );
+                }
+                catch ( Exception e ) {
+                    System.out.println("    : FAILED" );
+                    throw e;
+                }
+            }
+            System.out.println("    : PASSED" );
+        }
+
+        /*
+         * Create two new loggers to the list of Loggers already present
+         */
+        System.out.println("");
+        System.out.println( "*******************************" );
+        System.out.println( "*********** Phase 3 ***********" );
+        System.out.println( "*******************************" );
+        System.out.println( " Create and test new Loggers" );
+        Logger logger1 = Logger.getLogger( LOGGER_NAME_1 );
+        Logger logger2 = Logger.getLogger( LOGGER_NAME_2 );
+
+        // check that Level object are returned properly
+        try {
+            list = (String[]) mbs.getAttribute( objectName,  "LoggerNames" );
+        }
+        catch ( Exception e ) {
+            System.out.println("    : FAILED" );
+            throw e;
+        }
+
+        /*
+         *  Check for the existence of our new Loggers
+         */
+        boolean log1 = false, log2 = false;
+
+        if ( list == null || list.length < 2 ) {
+            System.out.println("    : FAILED.  Could not Detect the presense of the new Loggers" );
+            throw new RuntimeException(
+                "Could not Detect the presense of the new Loggers");
+        }
+        else {
+            for ( int i = 0; i < list.length; i++ ) {
+                if ( list[i].equals( LOGGER_NAME_1 ) ) {
+                    log1 = true;
+                    System.out.println( "    : Found new Logger : " + list[i] );
+                }
+                if ( list[i].equals( LOGGER_NAME_2 ) ) {
+                    log2 = true;
+                    System.out.println( "    : Found new Logger : " + list[i] );
+                }
+            }
+            if ( log1 && log2 )
+                System.out.println( "    : PASSED." );
+            else {
+                System.out.println( "    : FAILED.  Could not Detect the new Loggers." );
+                throw new RuntimeException(
+                    "Could not Detect the presense of the new Loggers");
+            }
+        }
+
+        /*
+         *  Set a new Logging levels and check that it succeeded
+         */
+        System.out.println("");
+        System.out.println( "*******************************" );
+        System.out.println( "*********** Phase 4 ***********" );
+        System.out.println( "*******************************" );
+        System.out.println( " Set and Check the Logger Level" );
+        log1 = false;
+        log2 = false;
+        try {
+            // Set the level of logger1 to ALL
+            params = new Object[2];
+            signature =  new String[2];
+            params[0] = LOGGER_NAME_1;
+            params[1] = Level.ALL.getName();
+            signature[0] = "java.lang.String";
+            signature[1] = "java.lang.String";
+            mbs.invoke(  objectName, "setLoggerLevel", params, signature );
+
+            // Set the level of logger2 to FINER
+            params[0] = LOGGER_NAME_2;
+            params[1] = Level.FINER.getName();
+            mbs.invoke(  objectName, "setLoggerLevel", params, signature );
+
+            // Okay read back the Level from Logger1. Should be ALL
+            params =  new Object[1];
+            signature =  new String[1];
+            params[0] = LOGGER_NAME_1;
+            signature[0] = "java.lang.String";
+            String levelName = (String) mbs.invoke(  objectName, "getLoggerLevel", params, signature );
+            l = Level.parse(levelName);
+            System.out.print("    Logger1: " );
+            if ( l.equals( l.ALL ) ) {
+                System.out.println("Level Set to ALL: PASSED" );
+                log1 = true;
+            }
+            else {
+                System.out.println("Level Set to ALL: FAILED" );
+                throw new RuntimeException(
+                    "Level Set to ALL but returned " + l.toString());
+            }
+
+            // Okay read back the Level from Logger2. Should be FINER
+            params =  new Object[1];
+            signature =  new String[1];
+            params[0] = LOGGER_NAME_2;
+            signature[0] = "java.lang.String";
+            levelName = (String) mbs.invoke(  objectName, "getLoggerLevel", params, signature );
+            l = Level.parse(levelName);
+            System.out.print("    Logger2: " );
+            if ( l.equals( l.FINER ) ) {
+                System.out.println("Level Set to FINER: PASSED" );
+                log2 = true;
+            }
+            else {
+                System.out.println("Level Set to FINER: FAILED" );
+                throw new RuntimeException(
+                    "Level Set to FINER but returned " + l.toString());
+            }
+        }
+        catch ( Exception e ) {
+            throw e;
+        }
+
+        System.out.println( "" );
+        System.out.println( "***************************************************" );
+        System.out.println( "***************** All Tests Passed ****************" );
+        System.out.println( "***************************************************" );
+    }
+
+    public static void main(String[] argv) throws Exception {
+        List<PlatformLoggingMXBean> result =
+            ManagementFactory.getPlatformMXBeans(PlatformLoggingMXBean.class);
+        if (result.size() != 1) {
+            throw new RuntimeException("Unexpected number of PlatformLoggingMXBean instances: " +
+                result.size());
+        }
+
+        PlatformLoggingMXBean mbean = result.get(0);
+        ObjectName objname = mbean.getObjectName();
+        if (!objname.equals(new ObjectName(LogManager.LOGGING_MXBEAN_NAME))) {
+            throw new RuntimeException("Invalid ObjectName " + objname);
+        }
+
+        // check if the PlatformLoggingMXBean is registered in the platform MBeanServer
+        MBeanServer platformMBS = ManagementFactory.getPlatformMBeanServer();
+        ObjectName objName = new ObjectName(LogManager.LOGGING_MXBEAN_NAME);
+        // We could call mbs.isRegistered(objName) here.
+        // Calling getMBeanInfo will throw exception if not found.
+        platformMBS.getMBeanInfo(objName);
+
+        if (!platformMBS.isInstanceOf(objName, "java.util.logging.PlatformLoggingMXBean") ||
+            !platformMBS.isInstanceOf(objName, "java.util.logging.LoggingMXBean")) {
+            throw new RuntimeException(objName + " is of unexpected type");
+        }
+
+        // test if PlatformLoggingMXBean works properly in a MBeanServer
+        PlatformLoggingMXBeanTest test = new PlatformLoggingMXBeanTest();
+        test.runTest(mbean);
+    }
+}