6882376: Add internal support for JRE implementation to eliminate the dependency on logging

Added sun.util.logging.PlatformLogger for JRE implementation to log messages.

Reviewed-by: alanb, naoto
This commit is contained in:
Mandy Chung 2009-09-17 14:24:55 -07:00
parent b43c00d17d
commit 70bee45623
9 changed files with 778 additions and 26 deletions

View File

@ -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)

View File

@ -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);
}
}
}

View File

@ -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<Object,Object>, 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 "

View File

@ -283,6 +283,10 @@ public class LogManager {
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;
}
});

View File

@ -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;
}
}
}
}

View File

@ -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);
}
}

View File

@ -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";
}
}
}

View File

@ -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 <tt>Preferences</tt>.
@ -48,7 +48,7 @@ class WindowsPreferences extends AbstractPreferences{
/**
* 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 @@ 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;
}

View File

@ -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());
}
}
}