Mercurial > hg > release > icedtea8-forest-3.0 > jdk
changeset 1740:d3281fa8e46c
6882376: Add internal support for JRE implementation to eliminate the dependency on logging
Summary: Added sun.util.logging.PlatformLogger for JRE implementation to log messages.
Reviewed-by: alanb, naoto
author | mchung |
---|---|
date | Thu, 17 Sep 2009 14:24:55 -0700 |
parents | 81b85ea694f8 |
children | 7b4e73ca6fd7 |
files | make/java/logging/Makefile src/share/classes/java/util/Currency.java src/share/classes/java/util/jar/Attributes.java src/share/classes/java/util/logging/LogManager.java src/share/classes/java/util/logging/LogRecord.java src/share/classes/sun/util/LocaleServiceProviderPool.java src/share/classes/sun/util/logging/PlatformLogger.java src/windows/classes/java/util/prefs/WindowsPreferences.java test/sun/util/logging/PlatformLoggerTest.java |
diffstat | 9 files changed, 778 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/make/java/logging/Makefile Wed Sep 16 09:23:50 2009 -0700 +++ b/make/java/logging/Makefile Thu Sep 17 14:24:55 2009 -0700 @@ -31,7 +31,7 @@ # # 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 @@ include $(BUILDDIR)/common/Classes.gmk properties: $(LIBDIR)/logging.properties - $(LIBDIR)/logging.properties: $(SHARE_SRC)/lib/logging.properties $(install-file)
--- a/src/share/classes/java/util/Currency.java Wed Sep 16 09:23:50 2009 -0700 +++ b/src/share/classes/java/util/Currency.java Thu Sep 17 14:24:55 2009 -0700 @@ -35,12 +35,12 @@ 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 @@ } } } 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 @@ .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 @@ .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 @@ 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); } } }
--- a/src/share/classes/java/util/jar/Attributes.java Wed Sep 16 09:23:50 2009 -0700 +++ b/src/share/classes/java/util/jar/Attributes.java Thu Sep 17 14:24:55 2009 -0700 @@ -34,7 +34,7 @@ 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 @@ } 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 "
--- a/src/share/classes/java/util/logging/LogManager.java Wed Sep 16 09:23:50 2009 -0700 +++ b/src/share/classes/java/util/logging/LogManager.java Thu Sep 17 14:24:55 2009 -0700 @@ -283,6 +283,10 @@ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { readConfiguration(); + + // Platform loggers begin to delegate to java.util.logging.Logger + sun.util.logging.PlatformLogger.redirectPlatformLoggers(); + return null; } });
--- a/src/share/classes/java/util/logging/LogRecord.java Wed Sep 16 09:23:50 2009 -0700 +++ b/src/share/classes/java/util/logging/LogRecord.java Thu Sep 17 14:24:55 2009 -0700 @@ -530,6 +530,7 @@ 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 @@ 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; + } } } }
--- a/src/share/classes/sun/util/LocaleServiceProviderPool.java Wed Sep 16 09:23:50 2009 -0700 +++ b/src/share/classes/sun/util/LocaleServiceProviderPool.java Thu Sep 17 14:24:55 2009 -0700 @@ -39,8 +39,8 @@ 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 @@ } }); } 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 @@ 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); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/util/logging/PlatformLogger.java Thu Sep 17 14:24:55 2009 -0700 @@ -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: + * <JAVA_HOME>/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 <JAVA_HOME>/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<Boolean>() { + 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<String,WeakReference<PlatformLogger>> loggers = + new HashMap<String,WeakReference<PlatformLogger>>(); + + /** + * Returns a PlatformLogger of a given name. + */ + public static synchronized PlatformLogger getLogger(String name) { + PlatformLogger log = null; + WeakReference<PlatformLogger> ref = loggers.get(name); + if (ref != null) { + log = ref.get(); + } + if (log == null) { + log = new PlatformLogger(name); + loggers.put(name, new WeakReference<PlatformLogger>(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<String, WeakReference<PlatformLogger>> entry : loggers.entrySet()) { + WeakReference<PlatformLogger> 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<String>() { + 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<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"); + 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<Integer, Object> 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"; + } + } + +}
--- a/src/windows/classes/java/util/prefs/WindowsPreferences.java Wed Sep 16 09:23:50 2009 -0700 +++ b/src/windows/classes/java/util/prefs/WindowsPreferences.java Thu Sep 17 14:24:55 2009 -0700 @@ -29,7 +29,7 @@ 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 <tt>Preferences</tt>. @@ -48,7 +48,7 @@ /** * Logger for error messages */ - private static Logger logger; + private static PlatformLogger logger; /** * Windows registry path to <tt>Preferences</tt>'s root nodes. @@ -1102,9 +1102,9 @@ // 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; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/util/logging/PlatformLoggerTest.java Thu Sep 17 14:24:55 2009 -0700 @@ -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()); + } + } +}