jdk/src/share/classes/java/util/logging/LogManager.java
Print this page
rev 5720 : 8005615: Java Logger fails to load tomcat logger implementation (JULI)
Reviewed-by: alanb, ahgross
*** 32,41 ****
--- 32,43 ----
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.net.URL;
+ import sun.misc.JavaAWTAccess;
+ import sun.misc.SharedSecrets;
import sun.security.action.GetPropertyAction;
/**
* There is a single global LogManager object that is used to
* maintain a set of shared state about Loggers and log services.
*** 153,166 ****
private Properties props = new Properties();
private PropertyChangeSupport changes
= new PropertyChangeSupport(LogManager.class);
private final static Level defaultLevel = Level.INFO;
! // Table of named Loggers that maps names to Loggers.
! private Hashtable<String,LoggerWeakRef> namedLoggers = new Hashtable<>();
! // Tree of named Loggers
! private LogNode root = new LogNode(null);
private Logger rootLogger;
// Have we done the primordial reading of the configuration file?
// (Must be done after a suitable amount of java.lang.System
// initialization has been done)
--- 155,167 ----
private Properties props = new Properties();
private PropertyChangeSupport changes
= new PropertyChangeSupport(LogManager.class);
private final static Level defaultLevel = Level.INFO;
! // LoggerContext for system loggers and user loggers
! private final LoggerContext systemContext = new SystemLoggerContext();
! private final LoggerContext userContext = new LoggerContext();
private Logger rootLogger;
// Have we done the primordial reading of the configuration file?
// (Must be done after a suitable amount of java.lang.System
// initialization has been done)
*** 195,204 ****
--- 196,206 ----
}
// Create and retain Logger for the root of the namespace.
manager.rootLogger = manager.new RootLogger();
manager.addLogger(manager.rootLogger);
+ manager.systemContext.addLocalLogger(manager.rootLogger);
// Adding the global Logger. Doing so in the Logger.<clinit>
// would deadlock with the LogManager.<clinit>.
Logger.global.setLogManager(manager);
manager.addLogger(Logger.global);
*** 277,294 ****
// bootstrapping phase
if (System.out == null) {
return;
}
readPrimordialConfiguration = true;
try {
! 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;
}
});
} catch (Exception ex) {
// System.err.println("Can't read logging configuration:");
--- 279,296 ----
// bootstrapping phase
if (System.out == null) {
return;
}
readPrimordialConfiguration = true;
+
try {
! AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
! public Void run() throws Exception {
readConfiguration();
// Platform loggers begin to delegate to java.util.logging.Logger
sun.util.logging.PlatformLogger.redirectPlatformLoggers();
return null;
}
});
} catch (Exception ex) {
// System.err.println("Can't read logging configuration:");
*** 335,358 ****
public void removePropertyChangeListener(PropertyChangeListener l) throws SecurityException {
checkPermission();
changes.removePropertyChangeListener(l);
}
! // Package-level method.
// Find or create a specified logger instance. If a logger has
// already been created with the given name it is returned.
// Otherwise a new logger instance is created and registered
// in the LogManager global namespace.
-
// This method will always return a non-null Logger object.
// Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by addLogger().
! Logger demandLogger(String name) {
Logger result = getLogger(name);
if (result == null) {
// only allocate the new logger once
! Logger newLogger = new Logger(name, null);
do {
if (addLogger(newLogger)) {
// We successfully added the new Logger that we
// created above so return it without refetching.
return newLogger;
--- 337,405 ----
public void removePropertyChangeListener(PropertyChangeListener l) throws SecurityException {
checkPermission();
changes.removePropertyChangeListener(l);
}
! // Returns the LoggerContext for the user code (i.e. application or AppContext).
! // Loggers are isolated from each AppContext.
! private LoggerContext getUserContext() {
! LoggerContext context = null;
!
! SecurityManager sm = System.getSecurityManager();
! JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess();
! if (sm != null && javaAwtAccess != null) {
! synchronized (javaAwtAccess) {
! // AppContext.getAppContext() returns the system AppContext if called
! // from a system thread but Logger.getLogger might be called from
! // an applet code. Instead, find the AppContext of the applet code
! // from the execution stack.
! Object ecx = javaAwtAccess.getExecutionContext();
! if (ecx == null) {
! // fall back to AppContext.getAppContext()
! ecx = javaAwtAccess.getContext();
! }
! context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class);
! if (context == null) {
! if (javaAwtAccess.isMainAppContext()) {
! context = userContext;
! } else {
! context = new LoggerContext();
! context.addLocalLogger(manager.rootLogger);
! }
! javaAwtAccess.put(ecx, LoggerContext.class, context);
! }
! }
! } else {
! context = userContext;
! }
! return context;
! }
!
! private List<LoggerContext> contexts() {
! List<LoggerContext> cxs = new ArrayList<>();
! cxs.add(systemContext);
! cxs.add(getUserContext());
! return cxs;
! }
!
// Find or create a specified logger instance. If a logger has
// already been created with the given name it is returned.
// Otherwise a new logger instance is created and registered
// in the LogManager global namespace.
// This method will always return a non-null Logger object.
// Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by addLogger().
! //
! // This method must delegate to the LogManager implementation to
! // add a new Logger or return the one that has been added previously
! // as a LogManager subclass may override the addLogger, getLogger,
! // readConfiguration, and other methods.
! Logger demandLogger(String name, String resourceBundleName) {
Logger result = getLogger(name);
if (result == null) {
// only allocate the new logger once
! Logger newLogger = new Logger(name, resourceBundleName);
do {
if (addLogger(newLogger)) {
// We successfully added the new Logger that we
// created above so return it without refetching.
return newLogger;
*** 373,445 ****
} while (result == null);
}
return result;
}
// If logger.getUseParentHandlers() returns 'true' and any of the logger's
// parents have levels or handlers defined, make sure they are instantiated.
! private void processParentHandlers(Logger logger, String name) {
int ix = 1;
for (;;) {
int ix2 = name.indexOf(".", ix);
if (ix2 < 0) {
break;
}
! String pname = name.substring(0,ix2);
!
! if (getProperty(pname+".level") != null ||
! getProperty(pname+".handlers") != null) {
// This pname has a level/handlers definition.
// Make sure it exists.
! demandLogger(pname);
}
ix = ix2+1;
}
}
// Add new per logger handlers.
// We need to raise privilege here. All our decisions will
// be made based on the logging configuration, which can
// only be modified by trusted code.
private void loadLoggerHandlers(final Logger logger, final String name,
! final String handlersPropertyName) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
- if (logger != rootLogger) {
- boolean useParent = getBooleanProperty(name + ".useParentHandlers", true);
- if (!useParent) {
- logger.setUseParentHandlers(false);
- }
- }
-
String names[] = parseClassNames(handlersPropertyName);
for (int i = 0; i < names.length; i++) {
String word = names[i];
try {
Class clz = ClassLoader.getSystemClassLoader().loadClass(word);
Handler hdl = (Handler) clz.newInstance();
- try {
// Check if there is a property defining the
// this handler's level.
String levs = getProperty(word + ".level");
if (levs != null) {
! hdl.setLevel(Level.parse(levs));
! }
! } catch (Exception ex) {
! System.err.println("Can't set level for " + word);
// Probably a bad level. Drop through.
}
// Add this Handler to the logger
logger.addHandler(hdl);
} catch (Exception ex) {
System.err.println("Can't load log handler \"" + word + "\"");
System.err.println("" + ex);
ex.printStackTrace();
}
}
return null;
! }});
}
// loggerRefQueue holds LoggerWeakRef objects for Logger objects
// that have been GC'ed.
--- 420,692 ----
} while (result == null);
}
return result;
}
+ Logger demandSystemLogger(String name, String resourceBundleName) {
+ return systemContext.demandLogger(name, resourceBundleName);
+ }
+
+ // LoggerContext maintains the logger namespace per context.
+ // The default LogManager implementation has one system context and user
+ // context. The system context is used to maintain the namespace for
+ // all system loggers and is queried by the system code. If a system logger
+ // doesn't exist in the user context, it'll also be added to the user context.
+ // The user context is queried by the user code and all other loggers are
+ // added in the user context.
+ static class LoggerContext {
+ // Table of named Loggers that maps names to Loggers.
+ private final Hashtable<String,LoggerWeakRef> namedLoggers = new Hashtable<>();
+ // Tree of named Loggers
+ private final LogNode root;
+
+ private LoggerContext() {
+ this.root = new LogNode(null, this);
+ }
+
+ Logger demandLogger(String name, String resourceBundleName) {
+ // a LogManager subclass may have its own implementation to add and
+ // get a Logger. So delegate to the LogManager to do the work.
+ return manager.demandLogger(name, resourceBundleName);
+ }
+
+ synchronized Logger findLogger(String name) {
+ LoggerWeakRef ref = namedLoggers.get(name);
+ if (ref == null) {
+ return null;
+ }
+ Logger logger = ref.get();
+ if (logger == null) {
+ // Hashtable holds stale weak reference
+ // to a logger which has been GC-ed.
+ removeLogger(name);
+ }
+ return logger;
+ }
+
+ // Add a logger to this context. This method will only set its level
+ // and process parent loggers. It doesn't set its handlers.
+ synchronized boolean addLocalLogger(Logger logger) {
+ final String name = logger.getName();
+ if (name == null) {
+ throw new NullPointerException();
+ }
+
+ // cleanup some Loggers that have been GC'ed
+ manager.drainLoggerRefQueueBounded();
+
+ LoggerWeakRef ref = namedLoggers.get(name);
+ if (ref != null) {
+ if (ref.get() == null) {
+ // It's possible that the Logger was GC'ed after the
+ // drainLoggerRefQueueBounded() call above so allow
+ // a new one to be registered.
+ removeLogger(name);
+ } else {
+ // We already have a registered logger with the given name.
+ return false;
+ }
+ }
+
+ // We're adding a new logger.
+ // Note that we are creating a weak reference here.
+ ref = manager.new LoggerWeakRef(logger);
+ namedLoggers.put(name, ref);
+
+ // Apply any initial level defined for the new logger.
+ Level level = manager.getLevelProperty(name + ".level", null);
+ if (level != null) {
+ doSetLevel(logger, level);
+ }
+
+ processParentHandlers(logger, name);
+
+ // Find the new node and its parent.
+ LogNode node = getNode(name);
+ node.loggerRef = ref;
+ Logger parent = null;
+ LogNode nodep = node.parent;
+ while (nodep != null) {
+ LoggerWeakRef nodeRef = nodep.loggerRef;
+ if (nodeRef != null) {
+ parent = nodeRef.get();
+ if (parent != null) {
+ break;
+ }
+ }
+ nodep = nodep.parent;
+ }
+
+ if (parent != null) {
+ doSetParent(logger, parent);
+ }
+ // Walk over the children and tell them we are their new parent.
+ node.walkAndSetParent(logger);
+ // new LogNode is ready so tell the LoggerWeakRef about it
+ ref.setNode(node);
+ return true;
+ }
+
+ void removeLogger(String name) {
+ namedLoggers.remove(name);
+ }
+
+ synchronized Enumeration<String> getLoggerNames() {
+ return namedLoggers.keys();
+ }
+
// If logger.getUseParentHandlers() returns 'true' and any of the logger's
// parents have levels or handlers defined, make sure they are instantiated.
! private void processParentHandlers(final Logger logger, final String name) {
! AccessController.doPrivileged(new PrivilegedAction<Void>() {
! public Void run() {
! if (logger != manager.rootLogger) {
! boolean useParent = manager.getBooleanProperty(name + ".useParentHandlers", true);
! if (!useParent) {
! logger.setUseParentHandlers(false);
! }
! }
! return null;
! }
! });
!
int ix = 1;
for (;;) {
int ix2 = name.indexOf(".", ix);
if (ix2 < 0) {
break;
}
! String pname = name.substring(0, ix2);
! if (manager.getProperty(pname + ".level") != null ||
! manager.getProperty(pname + ".handlers") != null) {
// This pname has a level/handlers definition.
// Make sure it exists.
! demandLogger(pname, null);
}
ix = ix2+1;
}
}
+ // Gets a node in our tree of logger nodes.
+ // If necessary, create it.
+ LogNode getNode(String name) {
+ if (name == null || name.equals("")) {
+ return root;
+ }
+ LogNode node = root;
+ while (name.length() > 0) {
+ int ix = name.indexOf(".");
+ String head;
+ if (ix > 0) {
+ head = name.substring(0, ix);
+ name = name.substring(ix + 1);
+ } else {
+ head = name;
+ name = "";
+ }
+ if (node.children == null) {
+ node.children = new HashMap<>();
+ }
+ LogNode child = node.children.get(head);
+ if (child == null) {
+ child = new LogNode(node, this);
+ node.children.put(head, child);
+ }
+ node = child;
+ }
+ return node;
+ }
+ }
+
+ static class SystemLoggerContext extends LoggerContext {
+ // Add a system logger in the system context's namespace as well as
+ // in the LogManager's namespace if not exist so that there is only
+ // one single logger of the given name. System loggers are visible
+ // to applications unless a logger of the same name has been added.
+ Logger demandLogger(String name, String resourceBundleName) {
+ Logger result = findLogger(name);
+ if (result == null) {
+ // only allocate the new system logger once
+ Logger newLogger = new Logger(name, resourceBundleName);
+ do {
+ if (addLocalLogger(newLogger)) {
+ // We successfully added the new Logger that we
+ // created above so return it without refetching.
+ result = newLogger;
+ } else {
+ // We didn't add the new Logger that we created above
+ // because another thread added a Logger with the same
+ // name after our null check above and before our call
+ // to addLogger(). We have to refetch the Logger because
+ // addLogger() returns a boolean instead of the Logger
+ // reference itself. However, if the thread that created
+ // the other Logger is not holding a strong reference to
+ // the other Logger, then it is possible for the other
+ // Logger to be GC'ed after we saw it in addLogger() and
+ // before we can refetch it. If it has been GC'ed then
+ // we'll just loop around and try again.
+ result = findLogger(name);
+ }
+ } while (result == null);
+ }
+ // Add the system logger to the LogManager's namespace if not exists
+ // The LogManager will set its handlers via the LogManager.addLogger method.
+ if (!manager.addLogger(result) && result.getHandlers().length == 0) {
+ // if logger already exists but handlers not set
+ final Logger l = manager.getLogger(name);
+ final Logger logger = result;
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ for (Handler hdl : l.getHandlers()) {
+ logger.addHandler(hdl);
+ }
+ return null;
+ }
+ });
+ }
+ return result;
+ }
+ }
+
// Add new per logger handlers.
// We need to raise privilege here. All our decisions will
// be made based on the logging configuration, which can
// only be modified by trusted code.
private void loadLoggerHandlers(final Logger logger, final String name,
! final String handlersPropertyName)
! {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
String names[] = parseClassNames(handlersPropertyName);
for (int i = 0; i < names.length; i++) {
String word = names[i];
try {
Class clz = ClassLoader.getSystemClassLoader().loadClass(word);
Handler hdl = (Handler) clz.newInstance();
// Check if there is a property defining the
// this handler's level.
String levs = getProperty(word + ".level");
if (levs != null) {
! Level l = Level.findLevel(levs);
! if (l != null) {
! hdl.setLevel(l);
! } else {
// Probably a bad level. Drop through.
+ System.err.println("Can't set level for " + word);
+ }
}
// Add this Handler to the logger
logger.addHandler(hdl);
} catch (Exception ex) {
System.err.println("Can't load log handler \"" + word + "\"");
System.err.println("" + ex);
ex.printStackTrace();
}
}
return null;
! }
! });
}
// loggerRefQueue holds LoggerWeakRef objects for Logger objects
// that have been GC'ed.
*** 480,490 ****
// dispose of this LoggerWeakRef object
void dispose() {
if (node != null) {
// if we have a LogNode, then we were a named Logger
// so clear namedLoggers weak ref to us
! manager.namedLoggers.remove(name);
name = null; // clear our ref to the Logger's name
node.loggerRef = null; // clear LogNode's weak ref to us
node = null; // clear our ref to LogNode
}
--- 727,737 ----
// dispose of this LoggerWeakRef object
void dispose() {
if (node != null) {
// if we have a LogNode, then we were a named Logger
// so clear namedLoggers weak ref to us
! node.context.removeLogger(name);
name = null; // clear our ref to the Logger's name
node.loggerRef = null; // clear LogNode's weak ref to us
node = null; // clear our ref to LogNode
}
*** 569,644 ****
* @param logger the new logger.
* @return true if the argument logger was registered successfully,
* false if a logger of that name already exists.
* @exception NullPointerException if the logger name is null.
*/
! public synchronized boolean addLogger(Logger logger) {
final String name = logger.getName();
if (name == null) {
throw new NullPointerException();
}
!
! // cleanup some Loggers that have been GC'ed
! drainLoggerRefQueueBounded();
!
! LoggerWeakRef ref = namedLoggers.get(name);
! if (ref != null) {
! if (ref.get() == null) {
! // It's possible that the Logger was GC'ed after the
! // drainLoggerRefQueueBounded() call above so allow
! // a new one to be registered.
! namedLoggers.remove(name);
! } else {
! // We already have a registered logger with the given name.
! return false;
! }
! }
!
! // We're adding a new logger.
! // Note that we are creating a weak reference here.
! ref = new LoggerWeakRef(logger);
! namedLoggers.put(name, ref);
!
! // Apply any initial level defined for the new logger.
! Level level = getLevelProperty(name+".level", null);
! if (level != null) {
! doSetLevel(logger, level);
! }
!
// Do we have a per logger handler too?
// Note: this will add a 200ms penalty
! loadLoggerHandlers(logger, name, name+".handlers");
! processParentHandlers(logger, name);
!
! // Find the new node and its parent.
! LogNode node = findNode(name);
! node.loggerRef = ref;
! Logger parent = null;
! LogNode nodep = node.parent;
! while (nodep != null) {
! LoggerWeakRef nodeRef = nodep.loggerRef;
! if (nodeRef != null) {
! parent = nodeRef.get();
! if (parent != null) {
! break;
! }
! }
! nodep = nodep.parent;
! }
!
! if (parent != null) {
! doSetParent(logger, parent);
! }
! // Walk over the children and tell them we are their new parent.
! node.walkAndSetParent(logger);
!
! // new LogNode is ready so tell the LoggerWeakRef about it
! ref.setNode(node);
!
return true;
}
-
// Private method to set a level on a logger.
// If necessary, we raise privilege before doing the call.
private static void doSetLevel(final Logger logger, final Level level) {
SecurityManager sm = System.getSecurityManager();
--- 816,840 ----
* @param logger the new logger.
* @return true if the argument logger was registered successfully,
* false if a logger of that name already exists.
* @exception NullPointerException if the logger name is null.
*/
! public boolean addLogger(Logger logger) {
final String name = logger.getName();
if (name == null) {
throw new NullPointerException();
}
! LoggerContext cx = getUserContext();
! if (cx.addLocalLogger(logger)) {
// Do we have a per logger handler too?
// Note: this will add a 200ms penalty
! loadLoggerHandlers(logger, name, name + ".handlers");
return true;
+ } else {
+ return false;
+ }
}
// Private method to set a level on a logger.
// If necessary, we raise privilege before doing the call.
private static void doSetLevel(final Logger logger, final Level level) {
SecurityManager sm = System.getSecurityManager();
*** 654,665 ****
logger.setLevel(level);
return null;
}});
}
-
-
// Private method to set a parent on a logger.
// If necessary, we raise privilege before doing the setParent call.
private static void doSetParent(final Logger logger, final Logger parent) {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
--- 850,859 ----
*** 674,713 ****
logger.setParent(parent);
return null;
}});
}
- // Find a node in our tree of logger nodes.
- // If necessary, create it.
- private LogNode findNode(String name) {
- if (name == null || name.equals("")) {
- return root;
- }
- LogNode node = root;
- while (name.length() > 0) {
- int ix = name.indexOf(".");
- String head;
- if (ix > 0) {
- head = name.substring(0,ix);
- name = name.substring(ix+1);
- } else {
- head = name;
- name = "";
- }
- if (node.children == null) {
- node.children = new HashMap<>();
- }
- LogNode child = node.children.get(head);
- if (child == null) {
- child = new LogNode(node);
- node.children.put(head, child);
- }
- node = child;
- }
- return node;
- }
-
/**
* Method to find a named logger.
* <p>
* Note that since untrusted code may create loggers with
* arbitrary names this method should not be relied on to
--- 868,877 ----
*** 719,740 ****
* the case where the Logger has been garbage collected.
* <p>
* @param name name of the logger
* @return matching logger or null if none is found
*/
! public synchronized Logger getLogger(String name) {
! LoggerWeakRef ref = namedLoggers.get(name);
! if (ref == null) {
! return null;
! }
! Logger logger = ref.get();
! if (logger == null) {
! // Hashtable holds stale weak reference
! // to a logger which has been GC-ed.
! namedLoggers.remove(name);
! }
! return logger;
}
/**
* Get an enumeration of known logger names.
* <p>
--- 883,894 ----
* the case where the Logger has been garbage collected.
* <p>
* @param name name of the logger
* @return matching logger or null if none is found
*/
! public Logger getLogger(String name) {
! return getUserContext().findLogger(name);
}
/**
* Get an enumeration of known logger names.
* <p>
*** 749,760 ****
* handle the case where the Logger has been garbage collected in the
* time since its name was returned by this method.
* <p>
* @return enumeration of logger name strings
*/
! public synchronized Enumeration<String> getLoggerNames() {
! return namedLoggers.keys();
}
/**
* Reinitialize the logging properties and reread the logging configuration.
* <p>
--- 903,914 ----
* handle the case where the Logger has been garbage collected in the
* time since its name was returned by this method.
* <p>
* @return enumeration of logger name strings
*/
! public Enumeration<String> getLoggerNames() {
! return getUserContext().getLoggerNames();
}
/**
* Reinitialize the logging properties and reread the logging configuration.
* <p>
*** 835,858 ****
props = new Properties();
// Since we are doing a reset we no longer want to initialize
// the global handlers, if they haven't been initialized yet.
initializedGlobalHandlers = true;
}
! Enumeration enum_ = getLoggerNames();
while (enum_.hasMoreElements()) {
! String name = (String)enum_.nextElement();
! resetLogger(name);
}
}
-
// Private method to reset an individual target logger.
! private void resetLogger(String name) {
! Logger logger = getLogger(name);
! if (logger == null) {
! return;
! }
// Close all the Logger's handlers.
Handler[] targets = logger.getHandlers();
for (int i = 0; i < targets.length; i++) {
Handler h = targets[i];
logger.removeHandler(h);
--- 989,1012 ----
props = new Properties();
// Since we are doing a reset we no longer want to initialize
// the global handlers, if they haven't been initialized yet.
initializedGlobalHandlers = true;
}
! for (LoggerContext cx : contexts()) {
! Enumeration<String> enum_ = cx.getLoggerNames();
while (enum_.hasMoreElements()) {
! String name = enum_.nextElement();
! Logger logger = cx.findLogger(name);
! if (logger != null) {
! resetLogger(logger);
! }
! }
}
}
// Private method to reset an individual target logger.
! private void resetLogger(Logger logger) {
// Close all the Logger's handlers.
Handler[] targets = logger.getHandlers();
for (int i = 0; i < targets.length; i++) {
Handler h = targets[i];
logger.removeHandler(h);
*** 860,869 ****
--- 1014,1024 ----
h.close();
} catch (Exception ex) {
// Problems closing a handler? Keep going...
}
}
+ String name = logger.getName();
if (name != null && name.equals("")) {
// This is the root logger.
logger.setLevel(defaultLevel);
} else {
logger.setLevel(null);
*** 1007,1021 ****
Level getLevelProperty(String name, Level defaultValue) {
String val = getProperty(name);
if (val == null) {
return defaultValue;
}
! try {
! return Level.parse(val.trim());
! } catch (Exception ex) {
! return defaultValue;
! }
}
// Package private method to get a filter property.
// We return an instance of the class named by the "name"
// property. If the property is not defined or has problems
--- 1162,1173 ----
Level getLevelProperty(String name, Level defaultValue) {
String val = getProperty(name);
if (val == null) {
return defaultValue;
}
! Level l = Level.findLevel(val.trim());
! return l != null ? l : defaultValue;
}
// Package private method to get a filter property.
// We return an instance of the class named by the "name"
// property. If the property is not defined or has problems
*** 1074,1084 ****
return;
}
loadLoggerHandlers(rootLogger, null, "handlers");
}
-
private final Permission controlPermission = new LoggingPermission("control", null);
void checkPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
--- 1226,1235 ----
*** 1102,1114 ****
// Nested class to represent a node in our tree of named loggers.
private static class LogNode {
HashMap<String,LogNode> children;
LoggerWeakRef loggerRef;
LogNode parent;
! LogNode(LogNode parent) {
this.parent = parent;
}
// Recursive method to walk the tree below a node and set
// a new parent logger.
void walkAndSetParent(Logger parent) {
--- 1253,1267 ----
// Nested class to represent a node in our tree of named loggers.
private static class LogNode {
HashMap<String,LogNode> children;
LoggerWeakRef loggerRef;
LogNode parent;
+ final LoggerContext context;
! LogNode(LogNode parent, LoggerContext context) {
this.parent = parent;
+ this.context = context;
}
// Recursive method to walk the tree below a node and set
// a new parent logger.
void walkAndSetParent(Logger parent) {
*** 1131,1141 ****
// We use a subclass of Logger for the root logger, so
// that we only instantiate the global handlers when they
// are first needed.
private class RootLogger extends Logger {
-
private RootLogger() {
super("", null);
setLevel(defaultLevel);
}
--- 1284,1293 ----
*** 1163,1173 ****
// Private method to be called when the configuration has
// changed to apply any level settings to any pre-existing loggers.
synchronized private void setLevelsOnExistingLoggers() {
! Enumeration enum_ = props.propertyNames();
while (enum_.hasMoreElements()) {
String key = (String)enum_.nextElement();
if (!key.endsWith(".level")) {
// Not a level definition.
continue;
--- 1315,1325 ----
// Private method to be called when the configuration has
// changed to apply any level settings to any pre-existing loggers.
synchronized private void setLevelsOnExistingLoggers() {
! Enumeration<?> enum_ = props.propertyNames();
while (enum_.hasMoreElements()) {
String key = (String)enum_.nextElement();
if (!key.endsWith(".level")) {
// Not a level definition.
continue;
*** 1177,1193 ****
Level level = getLevelProperty(key, null);
if (level == null) {
System.err.println("Bad level value for property: " + key);
continue;
}
! Logger l = getLogger(name);
if (l == null) {
continue;
}
l.setLevel(level);
}
}
// Management Support
private static LoggingMXBean loggingMXBean = null;
/**
* String representation of the
--- 1329,1347 ----
Level level = getLevelProperty(key, null);
if (level == null) {
System.err.println("Bad level value for property: " + key);
continue;
}
! for (LoggerContext cx : contexts()) {
! Logger l = cx.findLogger(name);
if (l == null) {
continue;
}
l.setLevel(level);
}
}
+ }
// Management Support
private static LoggingMXBean loggingMXBean = null;
/**
* String representation of the