summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew John Hughes <gnu_andrew@member.fsf.org>2008-06-02 02:07:50 +0000
committerAndrew John Hughes <gnu_andrew@member.fsf.org>2008-06-02 02:07:50 +0000
commit1c8f9a8109208fa0a6626bb0d3575580c2aa31a8 (patch)
tree36d304c0b0fb224eedb39f3722dff4cae6d1fb66
parenta0008d24b284ba1846fcc6cd8406c837d75dab7d (diff)
downloadclasspath-1c8f9a8109208fa0a6626bb0d3575580c2aa31a8.tar.gz
Backport fix for PR35974.
2008-04-18 Mario Torre <neugens@aicas.com> PR classpath/35974 * java/util/logging/Logger.java: fix a deadlock and reformat code. Now all the methods of the class get a lock on a static lock, this avoids a lock when getLogger and log are used concurrently.
-rw-r--r--ChangeLog7
-rw-r--r--java/util/logging/Logger.java1624
2 files changed, 803 insertions, 828 deletions
diff --git a/ChangeLog b/ChangeLog
index 689358af5..4349582dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-04-18 Mario Torre <neugens@aicas.com>
+
+ PR classpath/35974
+ * java/util/logging/Logger.java: fix a deadlock and reformat code.
+ Now all the methods of the class get a lock on a static lock, this
+ avoids a lock when getLogger and log are used concurrently.
+
2008-04-16 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* m4/gcc_attribute.m4 (GCC_ATTRIBUTE): Fix cache variable name.
diff --git a/java/util/logging/Logger.java b/java/util/logging/Logger.java
index 01ef8f522..f7157c176 100644
--- a/java/util/logging/Logger.java
+++ b/java/util/logging/Logger.java
@@ -45,110 +45,105 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
/**
- * A Logger is used for logging information about events. Usually, there
- * is a seprate logger for each subsystem or component, although there
- * is a shared instance for components that make only occasional use of
- * the logging framework.
- *
- * <p>It is common to name a logger after the name of a corresponding
- * Java package. Loggers are organized into a hierarchical namespace;
- * for example, the logger <code>"org.gnu.foo"</code> is the
- * <em>parent</em> of logger <code>"org.gnu.foo.bar"</code>.
- *
- * <p>A logger for a named subsystem can be obtained through {@link
- * java.util.logging.Logger#getLogger(java.lang.String)}. However,
- * only code which has been granted the permission to control the
- * logging infrastructure will be allowed to customize that logger.
- * Untrusted code can obtain a private, anonymous logger through
- * {@link #getAnonymousLogger()} if it wants to perform any
- * modifications to the logger.
- *
- * <p>FIXME: Write more documentation.
- *
+ * A Logger is used for logging information about events. Usually, there is a
+ * seprate logger for each subsystem or component, although there is a shared
+ * instance for components that make only occasional use of the logging
+ * framework.
+ * <p>
+ * It is common to name a logger after the name of a corresponding Java package.
+ * Loggers are organized into a hierarchical namespace; for example, the logger
+ * <code>"org.gnu.foo"</code> is the <em>parent</em> of logger
+ * <code>"org.gnu.foo.bar"</code>.
+ * <p>
+ * A logger for a named subsystem can be obtained through {@link
+ * java.util.logging.Logger#getLogger(java.lang.String)}. However, only code
+ * which has been granted the permission to control the logging infrastructure
+ * will be allowed to customize that logger. Untrusted code can obtain a
+ * private, anonymous logger through {@link #getAnonymousLogger()} if it wants
+ * to perform any modifications to the logger.
+ * <p>
+ * FIXME: Write more documentation.
+ *
* @author Sascha Brawer (brawer@acm.org)
*/
public class Logger
{
-
static final Logger root = new Logger("", null);
/**
- * A logger provided to applications that make only occasional use
- * of the logging framework, typically early prototypes. Serious
- * products are supposed to create and use their own Loggers, so
- * they can be controlled individually.
+ * A logger provided to applications that make only occasional use of the
+ * logging framework, typically early prototypes. Serious products are
+ * supposed to create and use their own Loggers, so they can be controlled
+ * individually.
*/
public static final Logger global;
+ /**
+ * Use to lock methods on this class instead of calling synchronize on methods
+ * to avoid deadlocks. Yeah, no kidding, we got them :)
+ */
+ private static final Object[] lock = new Object[0];
+
static
{
// Our class might be initialized from an unprivileged context
- global = (Logger) AccessController.doPrivileged
- (new PrivilegedAction()
- {
- public Object run()
- {
- return getLogger("global");
- }
- });
+ global = (Logger) AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return getLogger("global");
+ }
+ });
}
-
/**
- * The name of the Logger, or <code>null</code> if the logger is
- * anonymous.
- *
- * <p>A previous version of the GNU Classpath implementation granted
- * untrusted code the permission to control any logger whose name
- * was null. However, test code revealed that the Sun J2SE 1.4
- * reference implementation enforces the security control for any
- * logger that was not created through getAnonymousLogger, even if
- * it has a null name. Therefore, a separate flag {@link
- * Logger#anonymous} was introduced.
+ * The name of the Logger, or <code>null</code> if the logger is anonymous.
+ * <p>
+ * A previous version of the GNU Classpath implementation granted untrusted
+ * code the permission to control any logger whose name was null. However,
+ * test code revealed that the Sun J2SE 1.4 reference implementation enforces
+ * the security control for any logger that was not created through
+ * getAnonymousLogger, even if it has a null name. Therefore, a separate flag
+ * {@link Logger#anonymous} was introduced.
*/
private final String name;
-
/**
* The name of the resource bundle used for localization.
- *
- * <p>This variable cannot be declared as <code>final</code>
- * because its value can change as a result of calling
- * getLogger(String,String).
+ * <p>
+ * This variable cannot be declared as <code>final</code> because its value
+ * can change as a result of calling getLogger(String,String).
*/
private String resourceBundleName;
-
/**
* The resource bundle used for localization.
- *
- * <p>This variable cannot be declared as <code>final</code>
- * because its value can change as a result of calling
- * getLogger(String,String).
+ * <p>
+ * This variable cannot be declared as <code>final</code> because its value
+ * can change as a result of calling getLogger(String,String).
*/
private ResourceBundle resourceBundle;
private Filter filter;
private final List handlerList = new java.util.ArrayList(4);
+
private Handler[] handlers = new Handler[0];
/**
- * Indicates whether or not this logger is anonymous. While
- * a LoggingPermission is required for any modifications to
- * a normal logger, untrusted code can obtain an anonymous logger
- * and modify it according to its needs.
- *
- * <p>A previous version of the GNU Classpath implementation
- * granted access to every logger whose name was null.
- * However, test code revealed that the Sun J2SE 1.4 reference
- * implementation enforces the security control for any logger
- * that was not created through getAnonymousLogger, even
- * if it has a null name.
+ * Indicates whether or not this logger is anonymous. While a
+ * LoggingPermission is required for any modifications to a normal logger,
+ * untrusted code can obtain an anonymous logger and modify it according to
+ * its needs.
+ * <p>
+ * A previous version of the GNU Classpath implementation granted access to
+ * every logger whose name was null. However, test code revealed that the Sun
+ * J2SE 1.4 reference implementation enforces the security control for any
+ * logger that was not created through getAnonymousLogger, even if it has a
+ * null name.
*/
private boolean anonymous;
-
private boolean useParentHandlers;
private Level level;
@@ -156,29 +151,26 @@ public class Logger
private Logger parent;
/**
- * Constructs a Logger for a subsystem. Most applications do not
- * need to create new Loggers explicitly; instead, they should call
- * the static factory methods
- * {@link #getLogger(java.lang.String,java.lang.String) getLogger}
+ * Constructs a Logger for a subsystem. Most applications do not need to
+ * create new Loggers explicitly; instead, they should call the static factory
+ * methods {@link #getLogger(java.lang.String,java.lang.String) getLogger}
* (with ResourceBundle for localization) or
- * {@link #getLogger(java.lang.String) getLogger} (without
- * ResourceBundle), respectively.
- *
- * @param name the name for the logger, for example "java.awt"
- * or "com.foo.bar". The name should be based on
- * the name of the package issuing log records
- * and consist of dot-separated Java identifiers.
- *
- * @param resourceBundleName the name of a resource bundle
- * for localizing messages, or <code>null</code>
- * to indicate that messages do not need to be localized.
- *
+ * {@link #getLogger(java.lang.String) getLogger} (without ResourceBundle),
+ * respectively.
+ *
+ * @param name the name for the logger, for example "java.awt" or
+ * "com.foo.bar". The name should be based on the name of the
+ * package issuing log records and consist of dot-separated Java
+ * identifiers.
+ * @param resourceBundleName the name of a resource bundle for localizing
+ * messages, or <code>null</code> to indicate that messages do
+ * not need to be localized.
* @throws java.util.MissingResourceException if
- * <code>resourceBundleName</code> is not <code>null</code>
- * and no such bundle could be located.
+ * <code>resourceBundleName</code> is not <code>null</code>
+ * and no such bundle could be located.
*/
protected Logger(String name, String resourceBundleName)
- throws MissingResourceException
+ throws MissingResourceException
{
this.name = name;
this.resourceBundleName = resourceBundleName;
@@ -190,1002 +182,978 @@ public class Logger
level = null;
- /* This is null when the root logger is being constructed,
- * and the root logger afterwards.
+ /*
+ * This is null when the root logger is being constructed, and the root
+ * logger afterwards.
*/
parent = root;
useParentHandlers = (parent != null);
}
-
-
/**
- * Finds a registered logger for a subsystem, or creates one in
- * case no logger has been registered yet.
- *
- * @param name the name for the logger, for example "java.awt"
- * or "com.foo.bar". The name should be based on
- * the name of the package issuing log records
- * and consist of dot-separated Java identifiers.
- *
- * @throws IllegalArgumentException if a logger for the subsystem
- * identified by <code>name</code> has already been created,
- * but uses a a resource bundle for localizing messages.
- *
- * @throws NullPointerException if <code>name</code> is
- * <code>null</code>.
- *
- * @return a logger for the subsystem specified by <code>name</code>
- * that does not localize messages.
+ * Finds a registered logger for a subsystem, or creates one in case no logger
+ * has been registered yet.
+ *
+ * @param name the name for the logger, for example "java.awt" or
+ * "com.foo.bar". The name should be based on the name of the
+ * package issuing log records and consist of dot-separated Java
+ * identifiers.
+ * @throws IllegalArgumentException if a logger for the subsystem identified
+ * by <code>name</code> has already been created, but uses a a
+ * resource bundle for localizing messages.
+ * @throws NullPointerException if <code>name</code> is <code>null</code>.
+ * @return a logger for the subsystem specified by <code>name</code> that
+ * does not localize messages.
*/
public static Logger getLogger(String name)
{
return getLogger(name, null);
}
-
/**
- * Finds a registered logger for a subsystem, or creates one in case
- * no logger has been registered yet.
- *
- * <p>If a logger with the specified name has already been
- * registered, the behavior depends on the resource bundle that is
- * currently associated with the existing logger.
- *
- * <ul><li>If the existing logger uses the same resource bundle as
- * specified by <code>resourceBundleName</code>, the existing logger
- * is returned.</li>
- *
- * <li>If the existing logger currently does not localize messages,
- * the existing logger is modified to use the bundle specified by
- * <code>resourceBundleName</code>. The existing logger is then
- * returned. Therefore, all subsystems currently using this logger
- * will produce localized messages from now on.</li>
- *
- * <li>If the existing logger already has an associated resource
- * bundle, but a different one than specified by
- * <code>resourceBundleName</code>, an
- * <code>IllegalArgumentException</code> is thrown.</li></ul>
- *
- * @param name the name for the logger, for example "java.awt"
- * or "org.gnu.foo". The name should be based on
- * the name of the package issuing log records
- * and consist of dot-separated Java identifiers.
- *
- * @param resourceBundleName the name of a resource bundle
- * for localizing messages, or <code>null</code>
- * to indicate that messages do not need to be localized.
- *
+ * Finds a registered logger for a subsystem, or creates one in case no logger
+ * has been registered yet.
+ * <p>
+ * If a logger with the specified name has already been registered, the
+ * behavior depends on the resource bundle that is currently associated with
+ * the existing logger.
+ * <ul>
+ * <li>If the existing logger uses the same resource bundle as specified by
+ * <code>resourceBundleName</code>, the existing logger is returned.</li>
+ * <li>If the existing logger currently does not localize messages, the
+ * existing logger is modified to use the bundle specified by
+ * <code>resourceBundleName</code>. The existing logger is then returned.
+ * Therefore, all subsystems currently using this logger will produce
+ * localized messages from now on.</li>
+ * <li>If the existing logger already has an associated resource bundle, but
+ * a different one than specified by <code>resourceBundleName</code>, an
+ * <code>IllegalArgumentException</code> is thrown.</li>
+ * </ul>
+ *
+ * @param name the name for the logger, for example "java.awt" or
+ * "org.gnu.foo". The name should be based on the name of the
+ * package issuing log records and consist of dot-separated Java
+ * identifiers.
+ * @param resourceBundleName the name of a resource bundle for localizing
+ * messages, or <code>null</code> to indicate that messages do
+ * not need to be localized.
* @return a logger for the subsystem specified by <code>name</code>.
- *
* @throws java.util.MissingResourceException if
- * <code>resourceBundleName</code> is not <code>null</code>
- * and no such bundle could be located.
- *
- * @throws IllegalArgumentException if a logger for the subsystem
- * identified by <code>name</code> has already been created,
- * but uses a different resource bundle for localizing
- * messages.
- *
- * @throws NullPointerException if <code>name</code> is
- * <code>null</code>.
+ * <code>resourceBundleName</code> is not <code>null</code>
+ * and no such bundle could be located.
+ * @throws IllegalArgumentException if a logger for the subsystem identified
+ * by <code>name</code> has already been created, but uses a
+ * different resource bundle for localizing messages.
+ * @throws NullPointerException if <code>name</code> is <code>null</code>.
*/
public static Logger getLogger(String name, String resourceBundleName)
{
LogManager lm = LogManager.getLogManager();
- Logger result;
+ Logger result;
if (name == null)
throw new NullPointerException();
- /* Without synchronized(lm), it could happen that another thread
- * would create a logger between our calls to getLogger and
- * addLogger. While addLogger would indicate this by returning
- * false, we could not be sure that this other logger was still
- * existing when we called getLogger a second time in order
- * to retrieve it -- note that LogManager is only allowed to
- * keep weak references to registered loggers, so Loggers
- * can be garbage collected at any time in general, and between
- * our call to addLogger and our second call go getLogger
- * in particular.
- *
- * Of course, we assume here that LogManager.addLogger etc.
- * are synchronizing on the global LogManager object. There
- * is a comment in the implementation of LogManager.addLogger
- * referring to this comment here, so that any change in
- * the synchronization of LogManager will be reflected here.
+ /*
+ * Without synchronized(lm), it could happen that another thread would
+ * create a logger between our calls to getLogger and addLogger. While
+ * addLogger would indicate this by returning false, we could not be sure
+ * that this other logger was still existing when we called getLogger a
+ * second time in order to retrieve it -- note that LogManager is only
+ * allowed to keep weak references to registered loggers, so Loggers can be
+ * garbage collected at any time in general, and between our call to
+ * addLogger and our second call go getLogger in particular. Of course, we
+ * assume here that LogManager.addLogger etc. are synchronizing on the
+ * global LogManager object. There is a comment in the implementation of
+ * LogManager.addLogger referring to this comment here, so that any change
+ * in the synchronization of LogManager will be reflected here.
*/
- synchronized (lm)
- {
- result = lm.getLogger(name);
- if (result == null)
- {
- boolean couldBeAdded;
-
- result = new Logger(name, resourceBundleName);
- couldBeAdded = lm.addLogger(result);
- if (!couldBeAdded)
- throw new IllegalStateException("cannot register new logger");
- }
- else
+ synchronized (lock)
{
- /* The logger already exists. Make sure it uses
- * the same resource bundle for localizing messages.
- */
- String existingBundleName = result.getResourceBundleName();
-
- /* The Sun J2SE 1.4 reference implementation will return the
- * registered logger object, even if it does not have a resource
- * bundle associated with it. However, it seems to change the
- * resourceBundle of the registered logger to the bundle
- * whose name was passed to getLogger.
- */
- if ((existingBundleName == null) && (resourceBundleName != null))
- {
- /* If ResourceBundle.getBundle throws an exception, the
- * existing logger will be unchanged. This would be
- * different if the assignment to resourceBundleName
- * came first.
- */
- result.resourceBundle = ResourceBundle.getBundle(resourceBundleName);
- result.resourceBundleName = resourceBundleName;
- return result;
- }
-
- if ((existingBundleName != resourceBundleName)
- && ((existingBundleName == null)
- || !existingBundleName.equals(resourceBundleName)))
- {
- throw new IllegalArgumentException();
- }
+ synchronized (lm)
+ {
+ result = lm.getLogger(name);
+ if (result == null)
+ {
+ boolean couldBeAdded;
+
+ result = new Logger(name, resourceBundleName);
+ couldBeAdded = lm.addLogger(result);
+ if (! couldBeAdded)
+ throw new IllegalStateException("cannot register new logger");
+ }
+ else
+ {
+ /*
+ * The logger already exists. Make sure it uses the same
+ * resource bundle for localizing messages.
+ */
+ String existingBundleName = result.getResourceBundleName();
+
+ /*
+ * The Sun J2SE 1.4 reference implementation will return the
+ * registered logger object, even if it does not have a resource
+ * bundle associated with it. However, it seems to change the
+ * resourceBundle of the registered logger to the bundle whose
+ * name was passed to getLogger.
+ */
+ if ((existingBundleName == null) &&
+ (resourceBundleName != null))
+ {
+ /*
+ * If ResourceBundle.getBundle throws an exception, the
+ * existing logger will be unchanged. This would be
+ * different if the assignment to resourceBundleName came
+ * first.
+ */
+ result.resourceBundle =
+ ResourceBundle.getBundle(resourceBundleName);
+
+ result.resourceBundleName = resourceBundleName;
+ return result;
+ }
+
+ if ((existingBundleName != resourceBundleName)
+ && ((existingBundleName == null)
+ || !existingBundleName.equals(resourceBundleName)))
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
}
- }
return result;
}
-
/**
- * Creates a new, unnamed logger. Unnamed loggers are not
- * registered in the namespace of the LogManager, and no special
- * security permission is required for changing their state.
- * Therefore, untrusted applets are able to modify their private
- * logger instance obtained through this method.
- *
- * <p>The parent of the newly created logger will the the root
- * logger, from which the level threshold and the handlers are
- * inherited.
+ * Creates a new, unnamed logger. Unnamed loggers are not registered in the
+ * namespace of the LogManager, and no special security permission is required
+ * for changing their state. Therefore, untrusted applets are able to modify
+ * their private logger instance obtained through this method.
+ * <p>
+ * The parent of the newly created logger will the the root logger, from which
+ * the level threshold and the handlers are inherited.
*/
public static Logger getAnonymousLogger()
{
return getAnonymousLogger(null);
}
-
/**
- * Creates a new, unnamed logger. Unnamed loggers are not
- * registered in the namespace of the LogManager, and no special
- * security permission is required for changing their state.
- * Therefore, untrusted applets are able to modify their private
- * logger instance obtained through this method.
- *
- * <p>The parent of the newly created logger will the the root
- * logger, from which the level threshold and the handlers are
- * inherited.
- *
- * @param resourceBundleName the name of a resource bundle
- * for localizing messages, or <code>null</code>
- * to indicate that messages do not need to be localized.
- *
+ * Creates a new, unnamed logger. Unnamed loggers are not registered in the
+ * namespace of the LogManager, and no special security permission is required
+ * for changing their state. Therefore, untrusted applets are able to modify
+ * their private logger instance obtained through this method.
+ * <p>
+ * The parent of the newly created logger will the the root logger, from which
+ * the level threshold and the handlers are inherited.
+ *
+ * @param resourceBundleName the name of a resource bundle for localizing
+ * messages, or <code>null</code> to indicate that messages do
+ * not need to be localized.
* @throws java.util.MissingResourceException if
- * <code>resourceBundleName</code> is not <code>null</code>
- * and no such bundle could be located.
+ * <code>resourceBundleName</code> is not <code>null</code>
+ * and no such bundle could be located.
*/
public static Logger getAnonymousLogger(String resourceBundleName)
- throws MissingResourceException
+ throws MissingResourceException
{
- Logger result;
+ Logger result;
result = new Logger(null, resourceBundleName);
result.anonymous = true;
return result;
}
-
/**
- * Returns the name of the resource bundle that is being used for
- * localizing messages.
- *
- * @return the name of the resource bundle used for localizing messages,
- * or <code>null</code> if the parent's resource bundle
- * is used for this purpose.
+ * Returns the name of the resource bundle that is being used for localizing
+ * messages.
+ *
+ * @return the name of the resource bundle used for localizing messages, or
+ * <code>null</code> if the parent's resource bundle is used for
+ * this purpose.
*/
- public synchronized String getResourceBundleName()
+ public String getResourceBundleName()
{
- return resourceBundleName;
+ synchronized (lock)
+ {
+ return resourceBundleName;
+ }
}
-
/**
- * Returns the resource bundle that is being used for localizing
- * messages.
- *
- * @return the resource bundle used for localizing messages,
- * or <code>null</code> if the parent's resource bundle
- * is used for this purpose.
+ * Returns the resource bundle that is being used for localizing messages.
+ *
+ * @return the resource bundle used for localizing messages, or
+ * <code>null</code> if the parent's resource bundle is used for
+ * this purpose.
*/
- public synchronized ResourceBundle getResourceBundle()
+ public ResourceBundle getResourceBundle()
{
- return resourceBundle;
+ synchronized (lock)
+ {
+ return resourceBundle;
+ }
}
-
/**
- * Returns the severity level threshold for this <code>Handler</code>.
- * All log records with a lower severity level will be discarded;
- * a log record of the same or a higher level will be published
- * unless an installed <code>Filter</code> decides to discard it.
- *
- * @return the severity level below which all log messages will be
- * discarded, or <code>null</code> if the logger inherits
- * the threshold from its parent.
+ * Returns the severity level threshold for this <code>Handler</code>. All
+ * log records with a lower severity level will be discarded; a log record of
+ * the same or a higher level will be published unless an installed
+ * <code>Filter</code> decides to discard it.
+ *
+ * @return the severity level below which all log messages will be discarded,
+ * or <code>null</code> if the logger inherits the threshold from
+ * its parent.
*/
- public synchronized Level getLevel()
+ public Level getLevel()
{
- return level;
+ synchronized (lock)
+ {
+ return level;
+ }
}
-
/**
- * Returns whether or not a message of the specified level
- * would be logged by this logger.
- *
- * @throws NullPointerException if <code>level</code>
- * is <code>null</code>.
+ * Returns whether or not a message of the specified level would be logged by
+ * this logger.
+ *
+ * @throws NullPointerException if <code>level</code> is <code>null</code>.
*/
- public synchronized boolean isLoggable(Level level)
+ public boolean isLoggable(Level level)
{
- if (this.level != null)
- return this.level.intValue() <= level.intValue();
+ synchronized (lock)
+ {
+ if (this.level != null)
+ return this.level.intValue() <= level.intValue();
- if (parent != null)
- return parent.isLoggable(level);
- else
- return false;
+ if (parent != null)
+ return parent.isLoggable(level);
+ else
+ return false;
+ }
}
-
/**
- * Sets the severity level threshold for this <code>Handler</code>.
- * All log records with a lower severity level will be discarded
- * immediately. A log record of the same or a higher level will be
- * published unless an installed <code>Filter</code> decides to
- * discard it.
- *
- * @param level the severity level below which all log messages
- * will be discarded, or <code>null</code> to
- * indicate that the logger should inherit the
- * threshold from its parent.
- *
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted
- * the permission to control the logging infrastructure by
- * having LoggingPermission("control"). Untrusted code can
- * obtain an anonymous logger through the static factory method
- * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ * Sets the severity level threshold for this <code>Handler</code>. All log
+ * records with a lower severity level will be discarded immediately. A log
+ * record of the same or a higher level will be published unless an installed
+ * <code>Filter</code> decides to discard it.
+ *
+ * @param level the severity level below which all log messages will be
+ * discarded, or <code>null</code> to indicate that the logger
+ * should inherit the threshold from its parent.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
*/
- public synchronized void setLevel(Level level)
+ public void setLevel(Level level)
{
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
-
- this.level = level;
+ synchronized (lock)
+ {
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ this.level = level;
+ }
}
-
- public synchronized Filter getFilter()
+ public Filter getFilter()
{
- return filter;
+ synchronized (lock)
+ {
+ return filter;
+ }
}
-
/**
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted
- * the permission to control the logging infrastructure by
- * having LoggingPermission("control"). Untrusted code can
- * obtain an anonymous logger through the static factory method
- * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
*/
- public synchronized void setFilter(Filter filter)
- throws SecurityException
+ public void setFilter(Filter filter) throws SecurityException
{
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
-
- this.filter = filter;
+ synchronized (lock)
+ {
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ this.filter = filter;
+ }
}
-
-
-
/**
* Returns the name of this logger.
- *
- * @return the name of this logger, or <code>null</code> if
- * the logger is anonymous.
+ *
+ * @return the name of this logger, or <code>null</code> if the logger is
+ * anonymous.
*/
public String getName()
{
- /* Note that the name of a logger cannot be changed during
- * its lifetime, so no synchronization is needed.
+ /*
+ * Note that the name of a logger cannot be changed during its lifetime, so
+ * no synchronization is needed.
*/
return name;
}
-
/**
- * Passes a record to registered handlers, provided the record
- * is considered as loggable both by {@link #isLoggable(Level)}
- * and a possibly installed custom {@link #setFilter(Filter) filter}.
- *
- * <p>If the logger has been configured to use parent handlers,
- * the record will be forwarded to the parent of this logger
- * in addition to being processed by the handlers registered with
- * this logger.
- *
- * <p>The other logging methods in this class are convenience methods
- * that merely create a new LogRecord and pass it to this method.
- * Therefore, subclasses usually just need to override this single
- * method for customizing the logging behavior.
- *
+ * Passes a record to registered handlers, provided the record is considered
+ * as loggable both by {@link #isLoggable(Level)} and a possibly installed
+ * custom {@link #setFilter(Filter) filter}.
+ * <p>
+ * If the logger has been configured to use parent handlers, the record will
+ * be forwarded to the parent of this logger in addition to being processed by
+ * the handlers registered with this logger.
+ * <p>
+ * The other logging methods in this class are convenience methods that merely
+ * create a new LogRecord and pass it to this method. Therefore, subclasses
+ * usually just need to override this single method for customizing the
+ * logging behavior.
+ *
* @param record the log record to be inspected and possibly forwarded.
*/
- public synchronized void log(LogRecord record)
+ public void log(LogRecord record)
{
- if (!isLoggable(record.getLevel()))
- return;
-
- if ((filter != null) && !filter.isLoggable(record))
- return;
-
- /* If no logger name has been set for the log record,
- * use the name of this logger.
- */
- if (record.getLoggerName() == null)
- record.setLoggerName(name);
-
- /* Avoid that some other thread is changing the logger hierarchy
- * while we are traversing it.
- */
- synchronized (LogManager.getLogManager())
- {
- Logger curLogger = this;
-
- do
+ synchronized (lock)
{
- /* The Sun J2SE 1.4 reference implementation seems to call the
- * filter only for the logger whose log method is called,
- * never for any of its parents. Also, parent loggers publish
- * log record whatever their level might be. This is pretty
- * weird, but GNU Classpath tries to be as compatible as
- * possible to the reference implementation.
- */
- for (int i = 0; i < curLogger.handlers.length; i++)
- curLogger.handlers[i].publish(record);
-
- if (curLogger.getUseParentHandlers() == false)
- break;
-
- curLogger = curLogger.getParent();
+ if (!isLoggable(record.getLevel()))
+ return;
+
+ if ((filter != null) && ! filter.isLoggable(record))
+ return;
+
+ /*
+ * If no logger name has been set for the log record, use the name of
+ * this logger.
+ */
+ if (record.getLoggerName() == null)
+ record.setLoggerName(name);
+
+ /*
+ * Avoid that some other thread is changing the logger hierarchy while
+ * we are traversing it.
+ */
+ synchronized (LogManager.getLogManager())
+ {
+ Logger curLogger = this;
+
+ do
+ {
+ /*
+ * The Sun J2SE 1.4 reference implementation seems to call the
+ * filter only for the logger whose log method is called, never
+ * for any of its parents. Also, parent loggers publish log
+ * record whatever their level might be. This is pretty weird,
+ * but GNU Classpath tries to be as compatible as possible to
+ * the reference implementation.
+ */
+ for (int i = 0; i < curLogger.handlers.length; i++)
+ curLogger.handlers[i].publish(record);
+
+ if (curLogger.getUseParentHandlers() == false)
+ break;
+
+ curLogger = curLogger.getParent();
+ }
+ while (parent != null);
+ }
}
- while (parent != null);
- }
}
-
public void log(Level level, String message)
{
if (isLoggable(level))
log(level, message, (Object[]) null);
}
-
- public synchronized void log(Level level,
- String message,
- Object param)
+ public void log(Level level, String message, Object param)
{
- if (isLoggable(level))
+ synchronized (lock)
{
- StackTraceElement caller = getCallerStackFrame();
- logp(level,
- caller != null ? caller.getClassName() : "<unknown>",
- caller != null ? caller.getMethodName() : "<unknown>",
- message,
- param);
+ if (isLoggable(level))
+ {
+ StackTraceElement caller = getCallerStackFrame();
+ logp(level, caller != null ? caller.getClassName() : "<unknown>",
+ caller != null ? caller.getMethodName() : "<unknown>",
+ message, param);
+ }
}
}
-
- public synchronized void log(Level level,
- String message,
- Object[] params)
+ public void log(Level level, String message, Object[] params)
{
- if (isLoggable(level))
+ synchronized (lock)
{
- StackTraceElement caller = getCallerStackFrame();
- logp(level,
- caller != null ? caller.getClassName() : "<unknown>",
- caller != null ? caller.getMethodName() : "<unknown>",
- message,
- params);
+ if (isLoggable(level))
+ {
+ StackTraceElement caller = getCallerStackFrame();
+ logp(level, caller != null ? caller.getClassName() : "<unknown>",
+ caller != null ? caller.getMethodName() : "<unknown>",
+ message, params);
+
+ }
}
}
-
- public synchronized void log(Level level,
- String message,
- Throwable thrown)
+ public void log(Level level, String message, Throwable thrown)
{
- if (isLoggable(level))
+ synchronized (lock)
{
- StackTraceElement caller = getCallerStackFrame();
- logp(level,
- caller != null ? caller.getClassName() : "<unknown>",
- caller != null ? caller.getMethodName() : "<unknown>",
- message,
- thrown);
+ if (isLoggable(level))
+ {
+ StackTraceElement caller = getCallerStackFrame();
+ logp(level, caller != null ? caller.getClassName() : "<unknown>",
+ caller != null ? caller.getMethodName() : "<unknown>",
+ message, thrown);
+ }
}
}
-
- public synchronized void logp(Level level,
- String sourceClass,
- String sourceMethod,
- String message)
+ public void logp(Level level, String sourceClass, String sourceMethod,
+ String message)
{
- logp(level, sourceClass, sourceMethod, message,
- (Object[]) null);
+ synchronized (lock)
+ {
+ logp(level, sourceClass, sourceMethod, message, (Object[]) null);
+ }
}
-
- public synchronized void logp(Level level,
- String sourceClass,
- String sourceMethod,
- String message,
- Object param)
+ public void logp(Level level, String sourceClass, String sourceMethod,
+ String message, Object param)
{
- logp(level, sourceClass, sourceMethod, message,
- new Object[] { param });
- }
+ synchronized (lock)
+ {
+ logp(level, sourceClass, sourceMethod, message, new Object[] { param });
+ }
+ }
- private synchronized ResourceBundle findResourceBundle()
+ private ResourceBundle findResourceBundle()
{
- if (resourceBundle != null)
- return resourceBundle;
+ synchronized (lock)
+ {
+ if (resourceBundle != null)
+ return resourceBundle;
- if (parent != null)
- return parent.findResourceBundle();
+ if (parent != null)
+ return parent.findResourceBundle();
- return null;
+ return null;
+ }
}
-
- private synchronized void logImpl(Level level,
- String sourceClass,
- String sourceMethod,
- String message,
- Object[] params)
+ private void logImpl(Level level, String sourceClass, String sourceMethod,
+ String message, Object[] params)
{
- LogRecord rec = new LogRecord(level, message);
+ synchronized (lock)
+ {
+ LogRecord rec = new LogRecord(level, message);
- rec.setResourceBundle(findResourceBundle());
- rec.setSourceClassName(sourceClass);
- rec.setSourceMethodName(sourceMethod);
- rec.setParameters(params);
+ rec.setResourceBundle(findResourceBundle());
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setParameters(params);
- log(rec);
+ log(rec);
+ }
}
-
- public synchronized void logp(Level level,
- String sourceClass,
- String sourceMethod,
- String message,
- Object[] params)
+ public void logp(Level level, String sourceClass, String sourceMethod,
+ String message, Object[] params)
{
- logImpl(level, sourceClass, sourceMethod, message, params);
+ synchronized (lock)
+ {
+ logImpl(level, sourceClass, sourceMethod, message, params);
+ }
}
-
- public synchronized void logp(Level level,
- String sourceClass,
- String sourceMethod,
- String message,
- Throwable thrown)
+ public void logp(Level level, String sourceClass, String sourceMethod,
+ String message, Throwable thrown)
{
- LogRecord rec = new LogRecord(level, message);
+ synchronized (lock)
+ {
+ LogRecord rec = new LogRecord(level, message);
- rec.setResourceBundle(resourceBundle);
- rec.setSourceClassName(sourceClass);
- rec.setSourceMethodName(sourceMethod);
- rec.setThrown(thrown);
+ rec.setResourceBundle(resourceBundle);
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setThrown(thrown);
- log(rec);
+ log(rec);
+ }
}
-
- public synchronized void logrb(Level level,
- String sourceClass,
- String sourceMethod,
- String bundleName,
- String message)
+ public void logrb(Level level, String sourceClass, String sourceMethod,
+ String bundleName, String message)
{
- logrb(level, sourceClass, sourceMethod, bundleName,
- message, (Object[]) null);
+ synchronized (lock)
+ {
+ logrb(level, sourceClass, sourceMethod, bundleName, message,
+ (Object[]) null);
+ }
}
-
- public synchronized void logrb(Level level,
- String sourceClass,
- String sourceMethod,
- String bundleName,
- String message,
- Object param)
+ public void logrb(Level level, String sourceClass, String sourceMethod,
+ String bundleName, String message, Object param)
{
- logrb(level, sourceClass, sourceMethod, bundleName,
- message, new Object[] { param });
+ synchronized (lock)
+ {
+ logrb(level, sourceClass, sourceMethod, bundleName, message,
+ new Object[] { param });
+ }
}
-
- public synchronized void logrb(Level level,
- String sourceClass,
- String sourceMethod,
- String bundleName,
- String message,
- Object[] params)
+ public void logrb(Level level, String sourceClass, String sourceMethod,
+ String bundleName, String message, Object[] params)
{
- LogRecord rec = new LogRecord(level, message);
+ synchronized (lock)
+ {
+ LogRecord rec = new LogRecord(level, message);
- rec.setResourceBundleName(bundleName);
- rec.setSourceClassName(sourceClass);
- rec.setSourceMethodName(sourceMethod);
- rec.setParameters(params);
+ rec.setResourceBundleName(bundleName);
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setParameters(params);
- log(rec);
+ log(rec);
+ }
}
-
- public synchronized void logrb(Level level,
- String sourceClass,
- String sourceMethod,
- String bundleName,
- String message,
- Throwable thrown)
+ public void logrb(Level level, String sourceClass, String sourceMethod,
+ String bundleName, String message, Throwable thrown)
{
- LogRecord rec = new LogRecord(level, message);
+ synchronized (lock)
+ {
+ LogRecord rec = new LogRecord(level, message);
- rec.setResourceBundleName(bundleName);
- rec.setSourceClassName(sourceClass);
- rec.setSourceMethodName(sourceMethod);
- rec.setThrown(thrown);
+ rec.setResourceBundleName(bundleName);
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setThrown(thrown);
- log(rec);
+ log(rec);
+ }
}
-
- public synchronized void entering(String sourceClass,
- String sourceMethod)
+ public void entering(String sourceClass, String sourceMethod)
{
- if (isLoggable(Level.FINER))
- logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
+ }
}
-
- public synchronized void entering(String sourceClass,
- String sourceMethod,
- Object param)
+ public void entering(String sourceClass, String sourceMethod, Object param)
{
- if (isLoggable(Level.FINER))
- logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param);
+ }
}
-
- public synchronized void entering(String sourceClass,
- String sourceMethod,
- Object[] params)
+ public void entering(String sourceClass, String sourceMethod, Object[] params)
{
- if (isLoggable(Level.FINER))
- {
- StringBuffer buf = new StringBuffer(80);
- buf.append("ENTRY");
- for (int i = 0; i < params.length; i++)
+ synchronized (lock)
{
- buf.append(" {");
- buf.append(i);
- buf.append('}');
+ if (isLoggable(Level.FINER))
+ {
+ StringBuffer buf = new StringBuffer(80);
+ buf.append("ENTRY");
+ for (int i = 0; i < params.length; i++)
+ {
+ buf.append(" {");
+ buf.append(i);
+ buf.append('}');
+ }
+
+ logp(Level.FINER, sourceClass, sourceMethod, buf.toString(), params);
+ }
}
-
- logp(Level.FINER, sourceClass, sourceMethod, buf.toString(), params);
- }
}
-
- public synchronized void exiting(String sourceClass,
- String sourceMethod)
+ public void exiting(String sourceClass, String sourceMethod)
{
- if (isLoggable(Level.FINER))
- logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
+ }
}
-
- public synchronized void exiting(String sourceClass,
- String sourceMethod,
- Object result)
+ public void exiting(String sourceClass, String sourceMethod, Object result)
{
- if (isLoggable(Level.FINER))
- logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
+ }
}
-
- public synchronized void throwing(String sourceClass,
- String sourceMethod,
- Throwable thrown)
+ public void throwing(String sourceClass, String sourceMethod, Throwable thrown)
{
- if (isLoggable(Level.FINER))
- logp(Level.FINER, sourceClass, sourceMethod, "THROW", thrown);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "THROW", thrown);
+ }
}
-
/**
- * Logs a message with severity level SEVERE, indicating a serious
- * failure that prevents normal program execution. Messages at this
- * level should be understandable to an inexperienced, non-technical
- * end user. Ideally, they explain in simple words what actions the
- * user can take in order to resolve the problem.
- *
+ * Logs a message with severity level SEVERE, indicating a serious failure
+ * that prevents normal program execution. Messages at this level should be
+ * understandable to an inexperienced, non-technical end user. Ideally, they
+ * explain in simple words what actions the user can take in order to resolve
+ * the problem.
+ *
* @see Level#SEVERE
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void severe(String message)
+ public void severe(String message)
{
- if (isLoggable(Level.SEVERE))
- log(Level.SEVERE, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.SEVERE))
+ log(Level.SEVERE, message);
+ }
}
-
/**
- * Logs a message with severity level WARNING, indicating a
- * potential problem that does not prevent normal program execution.
- * Messages at this level should be understandable to an
- * inexperienced, non-technical end user. Ideally, they explain in
- * simple words what actions the user can take in order to resolve
- * the problem.
- *
+ * Logs a message with severity level WARNING, indicating a potential problem
+ * that does not prevent normal program execution. Messages at this level
+ * should be understandable to an inexperienced, non-technical end user.
+ * Ideally, they explain in simple words what actions the user can take in
+ * order to resolve the problem.
+ *
* @see Level#WARNING
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void warning(String message)
+ public void warning(String message)
{
- if (isLoggable(Level.WARNING))
- log(Level.WARNING, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.WARNING))
+ log(Level.WARNING, message);
+ }
}
-
/**
- * Logs a message with severity level INFO. {@link Level#INFO} is
- * intended for purely informational messages that do not indicate
- * error or warning situations. In the default logging
- * configuration, INFO messages will be written to the system
- * console. For this reason, the INFO level should be used only for
- * messages that are important to end users and system
- * administrators. Messages at this level should be understandable
- * to an inexperienced, non-technical user.
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * Logs a message with severity level INFO. {@link Level#INFO} is intended for
+ * purely informational messages that do not indicate error or warning
+ * situations. In the default logging configuration, INFO messages will be
+ * written to the system console. For this reason, the INFO level should be
+ * used only for messages that are important to end users and system
+ * administrators. Messages at this level should be understandable to an
+ * inexperienced, non-technical user.
+ *
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void info(String message)
+ public void info(String message)
{
- if (isLoggable(Level.INFO))
- log(Level.INFO, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.INFO))
+ log(Level.INFO, message);
+ }
}
-
/**
- * Logs a message with severity level CONFIG. {@link Level#CONFIG} is
- * intended for static configuration messages, for example about the
- * windowing environment, the operating system version, etc.
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource bundle. While
- * it is possible to pass <code>null</code>, this is not
- * recommended, since a logging message without text is unlikely
- * to be helpful.
+ * Logs a message with severity level CONFIG. {@link Level#CONFIG} is intended
+ * for static configuration messages, for example about the windowing
+ * environment, the operating system version, etc.
+ *
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void config(String message)
+ public void config(String message)
{
- if (isLoggable(Level.CONFIG))
- log(Level.CONFIG, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.CONFIG))
+ log(Level.CONFIG, message);
+ }
}
-
/**
- * Logs a message with severity level FINE. {@link Level#FINE} is
- * intended for messages that are relevant for developers using
- * the component generating log messages. Examples include minor,
- * recoverable failures, or possible inefficiencies.
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * Logs a message with severity level FINE. {@link Level#FINE} is intended for
+ * messages that are relevant for developers using the component generating
+ * log messages. Examples include minor, recoverable failures, or possible
+ * inefficiencies.
+ *
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void fine(String message)
+ public void fine(String message)
{
- if (isLoggable(Level.FINE))
- log(Level.FINE, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINE))
+ log(Level.FINE, message);
+ }
}
-
/**
- * Logs a message with severity level FINER. {@link Level#FINER} is
- * intended for rather detailed tracing, for example entering a
- * method, returning from a method, or throwing an exception.
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * Logs a message with severity level FINER. {@link Level#FINER} is intended
+ * for rather detailed tracing, for example entering a method, returning from
+ * a method, or throwing an exception.
+ *
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void finer(String message)
+ public void finer(String message)
{
- if (isLoggable(Level.FINER))
- log(Level.FINER, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINER))
+ log(Level.FINER, message);
+ }
}
-
/**
- * Logs a message with severity level FINEST. {@link Level#FINEST}
- * is intended for highly detailed tracing, for example reaching a
- * certain point inside the body of a method.
- *
- * @param message the message text, also used as look-up key if the
- * logger is localizing messages with a resource
- * bundle. While it is possible to pass
- * <code>null</code>, this is not recommended, since
- * a logging message without text is unlikely to be
- * helpful.
+ * Logs a message with severity level FINEST. {@link Level#FINEST} is intended
+ * for highly detailed tracing, for example reaching a certain point inside
+ * the body of a method.
+ *
+ * @param message the message text, also used as look-up key if the logger is
+ * localizing messages with a resource bundle. While it is possible
+ * to pass <code>null</code>, this is not recommended, since a
+ * logging message without text is unlikely to be helpful.
*/
- public synchronized void finest(String message)
+ public void finest(String message)
{
- if (isLoggable(Level.FINEST))
- log(Level.FINEST, message);
+ synchronized (lock)
+ {
+ if (isLoggable(Level.FINEST))
+ log(Level.FINEST, message);
+ }
}
-
/**
- * Adds a handler to the set of handlers that get notified
- * when a log record is to be published.
- *
+ * Adds a handler to the set of handlers that get notified when a log record
+ * is to be published.
+ *
* @param handler the handler to be added.
- *
- * @throws NullPointerException if <code>handler</code>
- * is <code>null</code>.
- *
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted
- * the permission to control the logging infrastructure by
- * having LoggingPermission("control"). Untrusted code can
- * obtain an anonymous logger through the static factory method
- * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ * @throws NullPointerException if <code>handler</code> is <code>null</code>.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
*/
- public synchronized void addHandler(Handler handler)
- throws SecurityException
+ public void addHandler(Handler handler) throws SecurityException
{
- if (handler == null)
- throw new NullPointerException();
-
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
-
- if (!handlerList.contains(handler))
- {
- handlerList.add(handler);
- handlers = getHandlers();
- }
+ synchronized (lock)
+ {
+ if (handler == null)
+ throw new NullPointerException();
+
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ if (! handlerList.contains(handler))
+ {
+ handlerList.add(handler);
+ handlers = getHandlers();
+ }
+ }
}
-
/**
- * Removes a handler from the set of handlers that get notified
- * when a log record is to be published.
- *
+ * Removes a handler from the set of handlers that get notified when a log
+ * record is to be published.
+ *
* @param handler the handler to be removed.
- *
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted the
- * permission to control the logging infrastructure by having
- * LoggingPermission("control"). Untrusted code can obtain an
- * anonymous logger through the static factory method {@link
- * #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
- *
- * @throws NullPointerException if <code>handler</code>
- * is <code>null</code>.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method {@link
+ * #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ * @throws NullPointerException if <code>handler</code> is <code>null</code>.
*/
- public synchronized void removeHandler(Handler handler)
- throws SecurityException
+ public void removeHandler(Handler handler) throws SecurityException
{
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
-
- if (handler == null)
- throw new NullPointerException();
-
- handlerList.remove(handler);
- handlers = getHandlers();
+ synchronized (lock)
+ {
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ if (handler == null)
+ throw new NullPointerException();
+
+ handlerList.remove(handler);
+ handlers = getHandlers();
+ }
}
-
/**
- * Returns the handlers currently registered for this Logger.
- * When a log record has been deemed as being loggable,
- * it will be passed to all registered handlers for
- * publication. In addition, if the logger uses parent handlers
- * (see {@link #getUseParentHandlers() getUseParentHandlers}
- * and {@link #setUseParentHandlers(boolean) setUseParentHandlers},
- * the log record will be passed to the parent's handlers.
+ * Returns the handlers currently registered for this Logger. When a log
+ * record has been deemed as being loggable, it will be passed to all
+ * registered handlers for publication. In addition, if the logger uses parent
+ * handlers (see {@link #getUseParentHandlers() getUseParentHandlers} and
+ * {@link #setUseParentHandlers(boolean) setUseParentHandlers}, the log
+ * record will be passed to the parent's handlers.
*/
- public synchronized Handler[] getHandlers()
+ public Handler[] getHandlers()
{
- /* We cannot return our internal handlers array
- * because we do not have any guarantee that the
- * caller would not change the array entries.
- */
- return (Handler[]) handlerList.toArray(new Handler[handlerList.size()]);
+ synchronized (lock)
+ {
+ /*
+ * We cannot return our internal handlers array because we do not have
+ * any guarantee that the caller would not change the array entries.
+ */
+ return (Handler[]) handlerList.toArray(new Handler[handlerList.size()]);
+ }
}
-
/**
- * Returns whether or not this Logger forwards log records to
- * handlers registered for its parent loggers.
- *
- * @return <code>false</code> if this Logger sends log records
- * merely to Handlers registered with itself;
- * <code>true</code> if this Logger sends log records
- * not only to Handlers registered with itself, but also
- * to those Handlers registered with parent loggers.
+ * Returns whether or not this Logger forwards log records to handlers
+ * registered for its parent loggers.
+ *
+ * @return <code>false</code> if this Logger sends log records merely to
+ * Handlers registered with itself; <code>true</code> if this Logger
+ * sends log records not only to Handlers registered with itself, but
+ * also to those Handlers registered with parent loggers.
*/
- public synchronized boolean getUseParentHandlers()
+ public boolean getUseParentHandlers()
{
- return useParentHandlers;
+ synchronized (lock)
+ {
+ return useParentHandlers;
+ }
}
-
/**
- * Sets whether or not this Logger forwards log records to
- * handlers registered for its parent loggers.
- *
- * @param useParentHandlers <code>false</code> to let this
- * Logger send log records merely to Handlers registered
- * with itself; <code>true</code> to let this Logger
- * send log records not only to Handlers registered
- * with itself, but also to those Handlers registered with
- * parent loggers.
- *
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted
- * the permission to control the logging infrastructure by
- * having LoggingPermission("control"). Untrusted code can
- * obtain an anonymous logger through the static factory method
- * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
- *
+ * Sets whether or not this Logger forwards log records to handlers registered
+ * for its parent loggers.
+ *
+ * @param useParentHandlers <code>false</code> to let this Logger send log
+ * records merely to Handlers registered with itself;
+ * <code>true</code> to let this Logger send log records not only
+ * to Handlers registered with itself, but also to those Handlers
+ * registered with parent loggers.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
*/
- public synchronized void setUseParentHandlers(boolean useParentHandlers)
+ public void setUseParentHandlers(boolean useParentHandlers)
{
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
-
- this.useParentHandlers = useParentHandlers;
+ synchronized (lock)
+ {
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ this.useParentHandlers = useParentHandlers;
+ }
}
-
/**
- * Returns the parent of this logger. By default, the parent is
- * assigned by the LogManager by inspecting the logger's name.
- *
- * @return the parent of this logger (as detemined by the LogManager
- * by inspecting logger names), the root logger if no other
- * logger has a name which is a prefix of this logger's name, or
- * <code>null</code> for the root logger.
+ * Returns the parent of this logger. By default, the parent is assigned by
+ * the LogManager by inspecting the logger's name.
+ *
+ * @return the parent of this logger (as detemined by the LogManager by
+ * inspecting logger names), the root logger if no other logger has a
+ * name which is a prefix of this logger's name, or <code>null</code>
+ * for the root logger.
*/
- public synchronized Logger getParent()
+ public Logger getParent()
{
- return parent;
+ synchronized (lock)
+ {
+ return parent;
+ }
}
-
/**
- * Sets the parent of this logger. Usually, applications do not
- * call this method directly. Instead, the LogManager will ensure
- * that the tree of loggers reflects the hierarchical logger
- * namespace. Basically, this method should not be public at all,
- * but the GNU implementation follows the API specification.
- *
- * @throws NullPointerException if <code>parent</code> is
- * <code>null</code>.
- *
- * @throws SecurityException if this logger is not anonymous, a
- * security manager exists, and the caller is not granted
- * the permission to control the logging infrastructure by
- * having LoggingPermission("control"). Untrusted code can
- * obtain an anonymous logger through the static factory method
- * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ * Sets the parent of this logger. Usually, applications do not call this
+ * method directly. Instead, the LogManager will ensure that the tree of
+ * loggers reflects the hierarchical logger namespace. Basically, this method
+ * should not be public at all, but the GNU implementation follows the API
+ * specification.
+ *
+ * @throws NullPointerException if <code>parent</code> is <code>null</code>.
+ * @throws SecurityException if this logger is not anonymous, a security
+ * manager exists, and the caller is not granted the permission to
+ * control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
*/
- public synchronized void setParent(Logger parent)
+ public void setParent(Logger parent)
{
- if (parent == null)
- throw new NullPointerException();
+ synchronized (lock)
+ {
+ if (parent == null)
+ throw new NullPointerException();
- if (this == root)
- throw new IllegalArgumentException(
- "the root logger can only have a null parent");
+ if (this == root)
+ throw new IllegalArgumentException(
+ "the root logger can only have a null parent");
- /* An application is allowed to control an anonymous logger
- * without having the permission to control the logging
- * infrastructure.
- */
- if (!anonymous)
- LogManager.getLogManager().checkAccess();
+ /*
+ * An application is allowed to control an anonymous logger without
+ * having the permission to control the logging infrastructure.
+ */
+ if (! anonymous)
+ LogManager.getLogManager().checkAccess();
- this.parent = parent;
+ this.parent = parent;
+ }
}
-
+
/**
- * Gets the StackTraceElement of the first class that is not this class.
- * That should be the initial caller of a logging method.
+ * Gets the StackTraceElement of the first class that is not this class. That
+ * should be the initial caller of a logging method.
+ *
* @return caller of the initial logging method or null if unknown.
*/
private StackTraceElement getCallerStackFrame()
@@ -1195,18 +1163,18 @@ public class Logger
int index = 0;
// skip to stackentries until this class
- while(index < stackTrace.length
- && !stackTrace[index].getClassName().equals(getClass().getName()))
+ while (index < stackTrace.length
+ && ! stackTrace[index].getClassName().equals(getClass().getName()))
index++;
// skip the stackentries of this class
- while(index < stackTrace.length
- && stackTrace[index].getClassName().equals(getClass().getName()))
+ while (index < stackTrace.length
+ && stackTrace[index].getClassName().equals(getClass().getName()))
index++;
return index < stackTrace.length ? stackTrace[index] : null;
}
-
+
/**
* Reset and close handlers attached to this logger. This function is package
* private because it must only be available to the LogManager.