From f77f33a1d50e747a485d705e39e01f7e3bef85b6 Mon Sep 17 00:00:00 2001 From: mchung Date: Tue, 27 Oct 2009 16:32:23 -0700 Subject: [PATCH] 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 --- .../lang/management/PlatformComponent.java | 12 +- .../classes/java/util/logging/LogManager.java | 10 +- .../classes/java/util/logging/Logging.java | 11 - .../java/util/logging/LoggingMXBean.java | 16 +- .../java/util/logging/LoggingProxyImpl.java | 102 +++++++ .../util/logging/PlatformLoggingMXBean.java | 60 ++++ .../management/ManagementFactoryHelper.java | 52 ++++ .../sun/util/logging/LoggingProxy.java | 63 ++++ .../sun/util/logging/LoggingSupport.java | 141 +++++++++ .../sun/util/logging/PlatformLogger.java | 78 +---- .../PlatformLoggingMXBeanTest.java | 279 ++++++++++++++++++ 11 files changed, 729 insertions(+), 95 deletions(-) create mode 100644 src/share/classes/java/util/logging/LoggingProxyImpl.java create mode 100644 src/share/classes/java/util/logging/PlatformLoggingMXBean.java create mode 100644 src/share/classes/sun/util/logging/LoggingProxy.java create mode 100644 src/share/classes/sun/util/logging/LoggingSupport.java create mode 100644 test/java/util/logging/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java diff --git a/src/share/classes/java/lang/management/PlatformComponent.java b/src/share/classes/java/lang/management/PlatformComponent.java index fbf930e67..e0d5d6834 100644 --- a/src/share/classes/java/lang/management/PlatformComponent.java +++ b/src/share/classes/java/lang/management/PlatformComponent.java @@ -30,8 +30,7 @@ import java.util.Collections; 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 @@ enum PlatformComponent { * Logging facility. */ LOGGING( - "java.util.logging.LoggingMXBean", + "java.util.logging.PlatformLoggingMXBean", "java.util.logging", "Logging", defaultKeyProperties(), - new MXBeanFetcher() { - public List getMXBeans() { - return Collections.singletonList(LogManager.getLoggingMXBean()); + new MXBeanFetcher() { + public List getMXBeans() { + return ManagementFactoryHelper.getLoggingMXBean(); } }), - /** * Buffer pools. */ diff --git a/src/share/classes/java/util/logging/LogManager.java b/src/share/classes/java/util/logging/LogManager.java index 4faea17d7..fe09557d6 100644 --- a/src/share/classes/java/util/logging/LogManager.java +++ b/src/share/classes/java/util/logging/LogManager.java @@ -1039,12 +1039,16 @@ public class LogManager { /** * Returns LoggingMXBean for managing loggers. - * The LoggingMXBean can also obtained from the - * {@link java.lang.management.ManagementFactory#getPlatformMBeanServer - * platform MBeanServer} method. + * An alternative way to manage loggers is using + * the {@link java.lang.management.ManagementFactory#getPlatformMXBeans(Class) + * ManagementFactory.getPlatformMXBeans} method as follows: + *
+     *     List<{@link PlatformLoggingMXBean}> result = ManagementFactory.getPlatformMXBeans(PlatformLoggingMXBean.class);
+     * 
* * @return a {@link LoggingMXBean} object. * + * @see PlatformLoggingMXBean * @see java.lang.management.ManagementFactory * @since 1.5 */ diff --git a/src/share/classes/java/util/logging/Logging.java b/src/share/classes/java/util/logging/Logging.java index f70c2cffb..9ce97a3cf 100644 --- a/src/share/classes/java/util/logging/Logging.java +++ b/src/share/classes/java/util/logging/Logging.java @@ -29,9 +29,6 @@ import java.util.Enumeration; 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 @@ class Logging implements LoggingMXBean { return p.getName(); } } - - public ObjectName getObjectName() { - try { - return ObjectName.getInstance(LogManager.LOGGING_MXBEAN_NAME); - } catch (MalformedObjectNameException e) { - throw new IllegalArgumentException(e); - } - } } diff --git a/src/share/classes/java/util/logging/LoggingMXBean.java b/src/share/classes/java/util/logging/LoggingMXBean.java index a3abe3c69..e9dda046a 100644 --- a/src/share/classes/java/util/logging/LoggingMXBean.java +++ b/src/share/classes/java/util/logging/LoggingMXBean.java @@ -25,7 +25,6 @@ package java.util.logging; -import java.lang.management.PlatformManagedObject; /** * The management interface for the logging facility. @@ -35,27 +34,26 @@ import java.lang.management.PlatformManagedObject; * MXBean * can be obtained by calling * the {@link LogManager#getLoggingMXBean} method or from the - * {@link java.lang.management.ManagementFactory#getPlatformMBeanServer - * platform MBeanServer} method. + * {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer + * platform MBeanServer}. * - *

The {@link javax.management.ObjectName ObjectName} for uniquely + * The {@link javax.management.ObjectName ObjectName} for uniquely * identifying the LoggingMXBean within an MBeanServer is: *

* {@link LogManager#LOGGING_MXBEAN_NAME * java.util.logging:type=Logging} *
* - * It can be obtained by calling the - * {@link PlatformManagedObject#getObjectName} method. - * - * @see java.lang.management.ManagementFactory#getPlatformMXBeans(Class) + * The instance registered in the platform MBeanServer 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 diff --git a/src/share/classes/java/util/logging/LoggingProxyImpl.java b/src/share/classes/java/util/logging/LoggingProxyImpl.java new file mode 100644 index 000000000..c6422412a --- /dev/null +++ b/src/share/classes/java/util/logging/LoggingProxyImpl.java @@ -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 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(); + } +} diff --git a/src/share/classes/java/util/logging/PlatformLoggingMXBean.java b/src/share/classes/java/util/logging/PlatformLoggingMXBean.java new file mode 100644 index 000000000..f994e285b --- /dev/null +++ b/src/share/classes/java/util/logging/PlatformLoggingMXBean.java @@ -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. + * + *

The {@link java.lang.management.ManagementFactory#getPlatformMXBeans(Class) + * ManagementFactory.getPlatformMXBeans} method can be used to obtain + * the {@code PlatformLoggingMXBean} object as follows: + *

+ *     ManagementFactory.getPlatformMXBeans(PlatformLoggingMXBean.class);
+ * 
+ * or from the {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer + * platform MBeanServer}. + * + * The {@link javax.management.ObjectName ObjectName} for uniquely + * identifying the LoggingMXBean within an MBeanServer is: + *
+ * java.util.logging:type=Logging + *
+ * + * 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 { +} diff --git a/src/share/classes/sun/management/ManagementFactoryHelper.java b/src/share/classes/sun/management/ManagementFactoryHelper.java index d91dd8dd1..1938d3959 100644 --- a/src/share/classes/sun/management/ManagementFactoryHelper.java +++ b/src/share/classes/sun/management/ManagementFactoryHelper.java @@ -40,7 +40,11 @@ import java.security.PrivilegedActionException; 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 @@ public class ManagementFactoryHelper { return result; } + public static List 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 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 getBufferPoolMXBeans() { List pools = new ArrayList(2); pools.add(createBufferPoolMXBean(sun.misc.SharedSecrets.getJavaNioAccess() diff --git a/src/share/classes/sun/util/logging/LoggingProxy.java b/src/share/classes/sun/util/logging/LoggingProxy.java new file mode 100644 index 000000000..7447434a5 --- /dev/null +++ b/src/share/classes/sun/util/logging/LoggingProxy.java @@ -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 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); +} diff --git a/src/share/classes/sun/util/logging/LoggingSupport.java b/src/share/classes/sun/util/logging/LoggingSupport.java new file mode 100644 index 000000000..775c2dbb4 --- /dev/null +++ b/src/share/classes/sun/util/logging/LoggingSupport.java @@ -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() { + 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 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); + } +} diff --git a/src/share/classes/sun/util/logging/PlatformLogger.java b/src/share/classes/sun/util/logging/PlatformLogger.java index e8523b81f..6fb5050dd 100644 --- a/src/share/classes/sun/util/logging/PlatformLogger.java +++ b/src/share/classes/sun/util/logging/PlatformLogger.java @@ -136,7 +136,7 @@ public class PlatformLogger { * 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> entry : loggers.entrySet()) { @@ -487,73 +487,22 @@ public class PlatformLogger { * 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 levelObjects = new HashMap(); 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 @@ public class PlatformLogger { 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 @@ public class PlatformLogger { * 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 l : levelObjects.entrySet()) { if (level == l.getValue()) { @@ -608,15 +557,14 @@ public class PlatformLogger { 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"; diff --git a/test/java/util/logging/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java b/test/java/util/logging/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java new file mode 100644 index 000000000..d83082719 --- /dev/null +++ b/test/java/util/logging/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java @@ -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 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); + } +} -- GitLab