diff --git a/make/java/logging/Makefile b/make/java/logging/Makefile index c6ed1879fecd64bf9d36d4fe0f2dc8061e5bef7e..444c1c63b5a76d35c182dd7667240ada67a58b8d 100644 --- a/make/java/logging/Makefile +++ b/make/java/logging/Makefile @@ -31,7 +31,7 @@ include $(BUILDDIR)/common/Defs.gmk # # Files to compile. # -AUTO_FILES_JAVA_DIRS = java/util/logging +AUTO_FILES_JAVA_DIRS = java/util/logging sun/util/logging # # Resources @@ -46,7 +46,6 @@ RESOURCE_BUNDLES_COMPILED_PROPERTIES = \ include $(BUILDDIR)/common/Classes.gmk properties: $(LIBDIR)/logging.properties - $(LIBDIR)/logging.properties: $(SHARE_SRC)/lib/logging.properties $(install-file) diff --git a/src/share/classes/java/util/Currency.java b/src/share/classes/java/util/Currency.java index 5c9124a90c87797e052fe9beb7cf75d64d9c4f2c..714bd3b2363b4eedc156f8c8b445127a511cdc64 100644 --- a/src/share/classes/java/util/Currency.java +++ b/src/share/classes/java/util/Currency.java @@ -35,12 +35,12 @@ import java.io.Serializable; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.logging.Level; -import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.spi.CurrencyNameProvider; import java.util.spi.LocaleServiceProvider; import sun.util.LocaleServiceProviderPool; +import sun.util.logging.PlatformLogger; import sun.util.resources.LocaleData; import sun.util.resources.OpenListResourceBundle; @@ -244,7 +244,7 @@ public final class Currency implements Serializable { } } } catch (IOException e) { - log(Level.INFO, "currency.properties is ignored because of an IOException", e); + info("currency.properties is ignored because of an IOException", e); } return null; } @@ -686,7 +686,7 @@ public final class Currency implements Serializable { .append("The entry in currency.properties for ") .append(ctry).append(" is ignored because of the invalid country code.") .toString(); - log(Level.INFO, message, null); + info(message, null); return; } @@ -698,7 +698,7 @@ public final class Currency implements Serializable { .append(ctry) .append(" is ignored because the value format is not recognized.") .toString(); - log(Level.INFO, message, null); + info(message, null); return; } @@ -726,13 +726,13 @@ public final class Currency implements Serializable { setMainTableEntry(ctry.charAt(0), ctry.charAt(1), entry); } - private static void log(Level level, String message, Throwable t) { - Logger logger = Logger.getLogger("java.util.Currency"); - if (logger.isLoggable(level)) { + private static void info(String message, Throwable t) { + PlatformLogger logger = PlatformLogger.getLogger("java.util.Currency"); + if (logger.isLoggable(PlatformLogger.INFO)) { if (t != null) { - logger.log(level, message, t); + logger.info(message, t); } else { - logger.log(level, message); + logger.info(message); } } } diff --git a/src/share/classes/java/util/jar/Attributes.java b/src/share/classes/java/util/jar/Attributes.java index 27a2aba8ef98596120d6a1c06e847932b6210ceb..e9a9e6e6f691707680aede942c7bf94a5d6c9941 100644 --- a/src/share/classes/java/util/jar/Attributes.java +++ b/src/share/classes/java/util/jar/Attributes.java @@ -34,7 +34,7 @@ import java.util.Set; import java.util.Collection; import java.util.AbstractSet; import java.util.Iterator; -import java.util.logging.Logger; +import sun.util.logging.PlatformLogger; import java.util.Comparator; import sun.misc.ASCIICaseInsensitiveComparator; @@ -419,7 +419,7 @@ public class Attributes implements Map, Cloneable { } try { if ((putValue(name, value) != null) && (!lineContinued)) { - Logger.getLogger("java.util.jar").warning( + PlatformLogger.getLogger("java.util.jar").warning( "Duplicate name in Manifest: " + name + ".\n" + "Ensure that the manifest does not " diff --git a/src/share/classes/java/util/logging/LogManager.java b/src/share/classes/java/util/logging/LogManager.java index e6412565a87ec94d238428c958204c674f84c1e3..4faea17d79e5e9689ed01c79660429524b287d15 100644 --- a/src/share/classes/java/util/logging/LogManager.java +++ b/src/share/classes/java/util/logging/LogManager.java @@ -283,6 +283,10 @@ public class LogManager { AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws Exception { readConfiguration(); + + // Platform loggers begin to delegate to java.util.logging.Logger + sun.util.logging.PlatformLogger.redirectPlatformLoggers(); + return null; } }); diff --git a/src/share/classes/java/util/logging/LogRecord.java b/src/share/classes/java/util/logging/LogRecord.java index 6e659ba4ea783827cce14f4ffd452bba7667f88c..e6706319ffadf4d728aef54045767712cbf5500b 100644 --- a/src/share/classes/java/util/logging/LogRecord.java +++ b/src/share/classes/java/util/logging/LogRecord.java @@ -530,6 +530,7 @@ public class LogRecord implements java.io.Serializable { 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 @@ -539,15 +540,18 @@ public class LogRecord implements java.io.Serializable { String cname = frame.getClassName(); if (lookingForLogger) { // Skip all frames until we have found the first logger frame. - if (cname.equals(logClassName)) { + if (cname.equals(logClassName) || cname.startsWith(plogClassName)) { lookingForLogger = false; } } else { - if (!cname.equals(logClassName)) { - // We've found the relevant frame. - setSourceClassName(cname); - setSourceMethodName(frame.getMethodName()); - return; + if (!cname.equals(logClassName) && !cname.startsWith(plogClassName)) { + // skip reflection call + if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) { + // We've found the relevant frame. + setSourceClassName(cname); + setSourceMethodName(frame.getMethodName()); + return; + } } } } diff --git a/src/share/classes/sun/util/LocaleServiceProviderPool.java b/src/share/classes/sun/util/LocaleServiceProviderPool.java index 8fd21c9ce0a003ee4654a7edae946397a0575e51..9fcfe5b7abc0fc983b07a373ae1f9186fdcac551 100644 --- a/src/share/classes/sun/util/LocaleServiceProviderPool.java +++ b/src/share/classes/sun/util/LocaleServiceProviderPool.java @@ -39,8 +39,8 @@ import java.util.ServiceLoader; import java.util.ServiceConfigurationError; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Logger; import java.util.spi.LocaleServiceProvider; +import sun.util.logging.PlatformLogger; import sun.util.resources.LocaleData; import sun.util.resources.OpenListResourceBundle; @@ -122,10 +122,15 @@ public final class LocaleServiceProviderPool { } }); } catch (PrivilegedActionException e) { - Logger.getLogger("sun.util.LocaleServiceProviderPool").config(e.toString()); + config(e.toString()); } } + private static void config(String message) { + PlatformLogger logger = PlatformLogger.getLogger("sun.util.LocaleServiceProviderPool"); + logger.config(message); + } + /** * Lazy loaded set of available locales. * Loading all locales is a very long operation. @@ -337,7 +342,7 @@ public final class LocaleServiceProviderPool { if (providersObj != null) { return providersObj; } else if (isObjectProvider) { - Logger.getLogger("sun.util.LocaleServiceProviderPool").config( + config( "A locale sensitive service provider returned null for a localized objects, which should not happen. provider: " + lsp + " locale: " + requested); } } diff --git a/src/share/classes/sun/util/logging/PlatformLogger.java b/src/share/classes/sun/util/logging/PlatformLogger.java new file mode 100644 index 0000000000000000000000000000000000000000..1f06654616f43ea8d1b10f35ef6a31f0ed8ee402 --- /dev/null +++ b/src/share/classes/sun/util/logging/PlatformLogger.java @@ -0,0 +1,629 @@ +/* + * 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.ref.WeakReference; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.io.File; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.logging.Logger; +import java.util.*; +import sun.misc.JavaLangAccess; +import sun.misc.SharedSecrets; + +/** + * Platform logger provides an API for the JRE components to log + * messages. This enables the runtime components to eliminate the + * static dependency of the logging facility and also defers the + * java.util.logging initialization until it is enabled. + * In addition, the PlatformLogger API can be used if the logging + * module does not exist. + * + * If the logging facility is not enabled, the platform loggers + * will output log messages per the default logging configuration + * (see below). In this implementation, it does not log the + * the stack frame information issuing the log message. + * + * When the logging facility is enabled (at startup or runtime), + * the java.util.logging.Logger will be created for each platform + * logger and all log messages will be forwarded to the Logger + * to handle. + * + * Logging facility is "enabled" when one of the following + * conditions is met: + * 1) a system property "java.util.logging.config.class" or + * "java.util.logging.config.file" is set + * 2) java.util.logging.LogManager or java.util.logging.Logger + * is referenced that will trigger the logging initialization. + * + * Default logging configuration: + * global logging level = INFO + * handlers = java.util.logging.ConsoleHandler + * java.util.logging.ConsoleHandler.level = INFO + * java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter + * + * Limitation: + * /lib/logging.properties is the system-wide logging + * configuration defined in the specification and read in the + * default case to configure any java.util.logging.Logger instances. + * Platform loggers will not detect if /lib/logging.properties + * is modified. In other words, unless the java.util.logging API + * is used at runtime or the logging system properties is set, + * the platform loggers will use the default setting described above. + * The platform loggers are designed for JDK developers use and + * this limitation can be workaround with setting + * -Djava.util.logging.config.file system property. + * + * @since 1.7 + */ +public class PlatformLogger { + // Same values as java.util.logging.Level for easy mapping + public static final int OFF = Integer.MAX_VALUE; + public static final int SEVERE = 1000; + public static final int WARNING = 900; + public static final int INFO = 800; + public static final int CONFIG = 700; + public static final int FINE = 500; + public static final int FINER = 400; + public static final int FINEST = 300; + public static final int ALL = Integer.MIN_VALUE; + + private static final int defaultLevel = INFO; + private static boolean loggingEnabled; + static { + loggingEnabled = AccessController.doPrivileged( + new PrivilegedAction() { + public Boolean run() { + String cname = System.getProperty("java.util.logging.config.class"); + String fname = System.getProperty("java.util.logging.config.file"); + return (cname != null || fname != null); + } + }); + } + + // Table of known loggers. Maps names to PlatformLoggers. + private static Map> loggers = + new HashMap>(); + + /** + * Returns a PlatformLogger of a given name. + */ + public static synchronized PlatformLogger getLogger(String name) { + PlatformLogger log = null; + WeakReference ref = loggers.get(name); + if (ref != null) { + log = ref.get(); + } + if (log == null) { + log = new PlatformLogger(name); + loggers.put(name, new WeakReference(log)); + } + return log; + } + + /** + * Initialize java.util.logging.Logger objects for all platform loggers. + * This method is called from LogManager.readPrimordialConfiguration(). + */ + public static synchronized void redirectPlatformLoggers() { + if (loggingEnabled || !JavaLogger.supported) return; + + loggingEnabled = true; + for (Map.Entry> entry : loggers.entrySet()) { + WeakReference ref = entry.getValue(); + PlatformLogger plog = ref.get(); + if (plog != null) { + plog.newJavaLogger(); + } + } + } + + /** + * Creates a new JavaLogger that the platform logger uses + */ + private void newJavaLogger() { + logger = new JavaLogger(logger.name, logger.effectiveLevel); + } + + // logger may be replaced with a JavaLogger object + // when the logging facility is enabled + private volatile LoggerProxy logger; + + private PlatformLogger(String name) { + if (loggingEnabled) { + this.logger = new JavaLogger(name); + } else { + this.logger = new LoggerProxy(name); + } + } + + /** + * A convenience method to test if the logger is turned off. + * (i.e. its level is OFF). + */ + public boolean isEnabled() { + return logger.isEnabled(); + } + + /** + * Gets the name for this platform logger. + */ + public String getName() { + return logger.name; + } + + /** + * Returns true if a message of the given level would actually + * be logged by this logger. + */ + public boolean isLoggable(int level) { + return logger.isLoggable(level); + } + + /** + * Gets the current log level. Returns 0 if the current effective level + * is not set (equivalent to Logger.getLevel() returns null). + */ + public int getLevel() { + return logger.getLevel(); + } + + /** + * Sets the log level. + */ + public void setLevel(int newLevel) { + logger.setLevel(newLevel); + } + + /** + * Logs a SEVERE message. + */ + public void severe(String msg) { + logger.doLog(SEVERE, msg); + } + + public void severe(String msg, Throwable t) { + logger.doLog(SEVERE, msg, t); + } + + public void severe(String msg, Object... params) { + logger.doLog(SEVERE, msg, params); + } + + /** + * Logs a WARNING message. + */ + public void warning(String msg) { + logger.doLog(WARNING, msg); + } + + public void warning(String msg, Throwable t) { + logger.doLog(WARNING, msg, t); + } + + public void warning(String msg, Object... params) { + logger.doLog(WARNING, msg, params); + } + + /** + * Logs an INFO message. + */ + public void info(String msg) { + logger.doLog(INFO, msg); + } + + public void info(String msg, Throwable t) { + logger.doLog(INFO, msg, t); + } + + public void info(String msg, Object... params) { + logger.doLog(INFO, msg, params); + } + + /** + * Logs a CONFIG message. + */ + public void config(String msg) { + logger.doLog(CONFIG, msg); + } + + public void config(String msg, Throwable t) { + logger.doLog(CONFIG, msg, t); + } + + public void config(String msg, Object... params) { + logger.doLog(CONFIG, msg, params); + } + + /** + * Logs a FINE message. + */ + public void fine(String msg) { + logger.doLog(FINE, msg); + } + + public void fine(String msg, Throwable t) { + logger.doLog(FINE, msg, t); + } + + public void fine(String msg, Object... params) { + logger.doLog(FINE, msg, params); + } + + /** + * Logs a FINER message. + */ + public void finer(String msg) { + logger.doLog(FINER, msg); + } + + public void finer(String msg, Throwable t) { + logger.doLog(FINER, msg, t); + } + + public void finer(String msg, Object... params) { + logger.doLog(FINER, msg, params); + } + + /** + * Logs a FINEST message. + */ + public void finest(String msg) { + logger.doLog(FINEST, msg); + } + + public void finest(String msg, Throwable t) { + logger.doLog(FINEST, msg, t); + } + + public void finest(String msg, Object... params) { + logger.doLog(FINEST, msg, params); + } + + /** + * Default platform logging support - output messages to + * System.err - equivalent to ConsoleHandler with SimpleFormatter. + */ + static class LoggerProxy { + private static final PrintStream defaultStream = System.err; + private static final String lineSeparator = AccessController.doPrivileged( + new PrivilegedAction() { + public String run() { + return System.getProperty("line.separator"); + } + }); + + final String name; + volatile int levelValue; + volatile int effectiveLevel = 0; // current effective level value + + LoggerProxy(String name) { + this(name, defaultLevel); + } + + LoggerProxy(String name, int level) { + this.name = name; + this.levelValue = level == 0 ? defaultLevel : level; + } + + boolean isEnabled() { + return levelValue != OFF; + } + + int getLevel() { + return effectiveLevel; + } + + void setLevel(int newLevel) { + levelValue = newLevel; + effectiveLevel = newLevel; + } + + void doLog(int level, String msg) { + if (level < levelValue || levelValue == OFF) { + return; + } + defaultStream.println(format(level, msg, null)); + } + + void doLog(int level, String msg, Throwable thrown) { + if (level < levelValue || levelValue == OFF) { + return; + } + defaultStream.println(format(level, msg, thrown)); + } + + void doLog(int level, String msg, Object... params) { + if (level < levelValue || levelValue == OFF) { + return; + } + String newMsg = formatMessage(msg, params); + defaultStream.println(format(level, newMsg, null)); + } + + public boolean isLoggable(int level) { + if (level < levelValue || levelValue == OFF) { + return false; + } + return true; + } + + private static final String format = "{0,date} {0,time}"; + + private Object args[] = new Object[1]; + private MessageFormat formatter; + private Date dat; + + // Copied from java.util.logging.Formatter.formatMessage + private String formatMessage(String format, Object... parameters) { + // Do the formatting. + try { + if (parameters == null || parameters.length == 0) { + // No parameters. Just return format string. + return format; + } + // Is it a java.text style format? + // Ideally we could match with + // Pattern.compile("\\{\\d").matcher(format).find()) + // However the cost is 14% higher, so we cheaply check for + // 1 of the first 4 parameters + if (format.indexOf("{0") >= 0 || format.indexOf("{1") >=0 || + format.indexOf("{2") >=0|| format.indexOf("{3") >=0) { + return java.text.MessageFormat.format(format, parameters); + } + return format; + } catch (Exception ex) { + // Formatting failed: use format string. + return format; + } + } + + private synchronized String format(int level, String msg, Throwable thrown) { + StringBuffer sb = new StringBuffer(); + // Minimize memory allocations here. + if (dat == null) { + dat = new Date(); + formatter = new MessageFormat(format); + } + dat.setTime(System.currentTimeMillis()); + args[0] = dat; + StringBuffer text = new StringBuffer(); + formatter.format(args, text, null); + sb.append(text); + sb.append(" "); + sb.append(getCallerInfo()); + sb.append(lineSeparator); + sb.append(PlatformLogger.getLevelName(level)); + sb.append(": "); + sb.append(msg); + if (thrown != null) { + try { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + thrown.printStackTrace(pw); + pw.close(); + sb.append(sw.toString()); + } catch (Exception ex) { + throw new AssertionError(ex); + } + } + + return sb.toString(); + } + + // Returns the caller's class and method's name; best effort + // if cannot infer, return the logger's name. + private String getCallerInfo() { + String sourceClassName = null; + String sourceMethodName = null; + + JavaLangAccess access = SharedSecrets.getJavaLangAccess(); + Throwable throwable = new Throwable(); + int depth = access.getStackTraceDepth(throwable); + + String logClassName = "sun.util.logging.PlatformLogger"; + boolean lookingForLogger = true; + for (int ix = 0; ix < depth; ix++) { + // Calling getStackTraceElement directly prevents the VM + // from paying the cost of building the entire stack frame. + StackTraceElement frame = + access.getStackTraceElement(throwable, ix); + String cname = frame.getClassName(); + if (lookingForLogger) { + // Skip all frames until we have found the first logger frame. + if (cname.equals(logClassName)) { + lookingForLogger = false; + } + } else { + if (!cname.equals(logClassName)) { + // We've found the relevant frame. + sourceClassName = cname; + sourceMethodName = frame.getMethodName(); + break; + } + } + } + + if (sourceClassName != null) { + return sourceClassName + " " + sourceMethodName; + } else { + return name; + } + } + } + + /** + * JavaLogger forwards all the calls to its corresponding + * 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 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"); + 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) { + // 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); + } + } + + private final Object javaLogger; + JavaLogger(String name) { + this(name, 0); + } + + JavaLogger(String name, int level) { + super(name, level); + this.javaLogger = invoke(getLoggerMethod, null, name); + if (level != 0) { + // level has been updated and so set the Logger's level + invoke(setLevelMethod, javaLogger, levelObjects.get(level)); + } + } + + /** + * Let Logger.log() do the filtering since if the level of a + * platform logger is altered directly from + * java.util.logging.Logger.setLevel(), the levelValue will + * not be updated. + */ + void doLog(int level, String msg) { + invoke(logMethod, javaLogger, levelObjects.get(level), msg); + } + + void doLog(int level, String msg, Throwable t) { + invoke(logThrowMethod, javaLogger, levelObjects.get(level), msg, t); + } + + void doLog(int level, String msg, Object... params) { + invoke(logParamsMethod, javaLogger, levelObjects.get(level), msg, params); + } + + boolean isEnabled() { + Object level = invoke(getLevelMethod, javaLogger); + return level == null || level.equals(levelObjects.get(OFF)) == false; + } + + int getLevel() { + Object level = invoke(getLevelMethod, javaLogger); + if (level != null) { + for (Map.Entry l : levelObjects.entrySet()) { + if (level == l.getValue()) { + return l.getKey(); + } + } + } + return 0; + } + + void setLevel(int newLevel) { + levelValue = newLevel; + invoke(setLevelMethod, javaLogger, levelObjects.get(newLevel)); + } + } + + + private static String getLevelName(int level) { + switch (level) { + case OFF : return "OFF"; + case SEVERE : return "SEVERE"; + case WARNING : return "WARNING"; + case INFO : return "INFO"; + case CONFIG : return "CONFIG"; + case FINE : return "FINE"; + case FINER : return "FINER"; + case FINEST : return "FINEST"; + case ALL : return "ALL"; + default : return "UNKNOWN"; + } + } + +} diff --git a/src/windows/classes/java/util/prefs/WindowsPreferences.java b/src/windows/classes/java/util/prefs/WindowsPreferences.java index b9ee8f49b283bd4e9d278582cb522401cd235d5e..c9034277360e915d36c3e384d006ff32a1ab9a7a 100644 --- a/src/windows/classes/java/util/prefs/WindowsPreferences.java +++ b/src/windows/classes/java/util/prefs/WindowsPreferences.java @@ -29,7 +29,7 @@ import java.util.Map; import java.util.TreeMap; import java.util.StringTokenizer; import java.io.ByteArrayOutputStream; -import java.util.logging.Logger; +import sun.util.logging.PlatformLogger; /** * Windows registry based implementation of Preferences. @@ -48,7 +48,7 @@ class WindowsPreferences extends AbstractPreferences{ /** * Logger for error messages */ - private static Logger logger; + private static PlatformLogger logger; /** * Windows registry path to Preferences's root nodes. @@ -1102,9 +1102,9 @@ class WindowsPreferences extends AbstractPreferences{ // assert false; } - private static synchronized Logger logger() { + private static synchronized PlatformLogger logger() { if (logger == null) { - logger = Logger.getLogger("java.util.prefs"); + logger = PlatformLogger.getLogger("java.util.prefs"); } return logger; } diff --git a/test/sun/util/logging/PlatformLoggerTest.java b/test/sun/util/logging/PlatformLoggerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0c5daf0422e9f40e7666821b691667a2c086525e --- /dev/null +++ b/test/sun/util/logging/PlatformLoggerTest.java @@ -0,0 +1,111 @@ +/* + * 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. + * + * 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 6882376 + * @summary Test if java.util.logging.Logger is created before and after + * logging is enabled. Also validate some basic PlatformLogger + * operations. + * + * @build PlatformLoggerTest + * @run main PlatformLoggerTest + */ + +import java.util.logging.*; +import sun.util.logging.PlatformLogger; + +public class PlatformLoggerTest { + private static final int defaultEffectiveLevel = 0; + public static void main(String[] args) throws Exception { + final String FOO_PLATFORM_LOGGER = "test.platformlogger.foo"; + final String BAR_PLATFORM_LOGGER = "test.platformlogger.bar"; + final String GOO_PLATFORM_LOGGER = "test.platformlogger.goo"; + final String BAR_LOGGER = "test.logger.bar"; + PlatformLogger goo = PlatformLogger.getLogger(GOO_PLATFORM_LOGGER); + + // Create a platform logger using the default + PlatformLogger foo = PlatformLogger.getLogger(FOO_PLATFORM_LOGGER); + checkPlatformLogger(foo, FOO_PLATFORM_LOGGER); + + // create a java.util.logging.Logger + // now java.util.logging.Logger should be created for each platform logger + Logger logger = Logger.getLogger(BAR_LOGGER); + logger.setLevel(Level.WARNING); + + PlatformLogger bar = PlatformLogger.getLogger(BAR_PLATFORM_LOGGER); + checkPlatformLogger(bar, BAR_PLATFORM_LOGGER); + + checkLogger(FOO_PLATFORM_LOGGER, Level.FINER); + checkLogger(BAR_PLATFORM_LOGGER, Level.FINER); + + checkLogger(GOO_PLATFORM_LOGGER, null); + checkLogger(BAR_LOGGER, Level.WARNING); + + foo.setLevel(PlatformLogger.SEVERE); + checkLogger(FOO_PLATFORM_LOGGER, Level.SEVERE); + } + + private static void checkPlatformLogger(PlatformLogger logger, String name) { + if (!logger.getName().equals(name)) { + throw new RuntimeException("Invalid logger's name " + + logger.getName() + " but expected " + name); + } + + if (logger.getLevel() != defaultEffectiveLevel) { + throw new RuntimeException("Invalid default level for logger " + + logger.getName()); + } + + if (logger.isLoggable(PlatformLogger.FINE) != false) { + throw new RuntimeException("isLoggerable(FINE) returns true for logger " + + logger.getName() + " but expected false"); + } + + logger.setLevel(PlatformLogger.FINER); + if (logger.getLevel() != Level.FINER.intValue()) { + throw new RuntimeException("Invalid level for logger " + + logger.getName() + " " + logger.getLevel()); + } + + if (logger.isLoggable(PlatformLogger.FINE) != true) { + throw new RuntimeException("isLoggerable(FINE) returns false for logger " + + logger.getName() + " but expected true"); + } + + logger.info("OK: Testing log message"); + } + + private static void checkLogger(String name, Level level) { + Logger logger = LogManager.getLogManager().getLogger(name); + if (logger == null) { + throw new RuntimeException("Logger " + name + + " does not exist"); + } + + if (logger.getLevel() != level) { + throw new RuntimeException("Invalid level for logger " + + logger.getName() + " " + logger.getLevel()); + } + } +}