summaryrefslogtreecommitdiff
path: root/java/util
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2006-04-03 08:59:52 +0000
committerMark Wielaard <mark@klomp.org>2006-04-03 08:59:52 +0000
commitd01509a789e7113bae8b2750611b8b272af291b2 (patch)
tree76ecf32c99e3f9d28be90add68c75cbc5763be5e /java/util
parent5d64c983d7dfdb866cc47abe2bbfcdd76196065d (diff)
downloadclasspath-d01509a789e7113bae8b2750611b8b272af291b2.tar.gz
2006-04-03 Rafael H. Schloming <rafaels@redhat.com>
Fixes bug #26668 * java/util/logging/Level.java (parse): Document. * java/util/logging/LogManager.java (rootLogger): Removed. (LogManager): Just set loggers to new HashMap. (getLogManager): Make synchronized. Create and init LogManager if it doesn't exist yet. (static): Removed block. (MANAGER_PROPERTY): New private final string. (makeLogManager): Use new property string, move warning to createInstance() method. (CONFIG_PROPERTY): New private final string. (initLogManager): New method. (addLogger): Use Logger.root, not rootLogger. (findAncestor): Likewise. (readConfiguration): Move warning to createInstance() method. Add handlers directly to Logger.root. Warn about bad level values. (getClassProperty): Use new locateClass() method. (getInstanceProperty): Only catch specific newInstance Errors. (createInstance): Make private and takes a string to use in warning messages. Use new locateClass() method and generate appropriate warning message. (warn): New methods. (locateClass): Locates a class through the context class loader and system class loader as backup. * java/util/logging/Logger.java (root): New static final field. (Logger): Set parent to root. (setParent): Directly check root field.
Diffstat (limited to 'java/util')
-rw-r--r--java/util/logging/Level.java5
-rw-r--r--java/util/logging/LogManager.java293
-rw-r--r--java/util/logging/Logger.java15
3 files changed, 178 insertions, 135 deletions
diff --git a/java/util/logging/Level.java b/java/util/logging/Level.java
index 2c400dc3a..48ff318a4 100644
--- a/java/util/logging/Level.java
+++ b/java/util/logging/Level.java
@@ -1,5 +1,5 @@
/* Level.java -- a class for indicating logging levels
- Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -341,6 +341,9 @@ public class Level implements Serializable
for (int i = 0; i < knownLevels.length; i++)
{
+ // It's safe to use == instead of .equals here because only the
+ // standard logging levels will be returned by this method, and
+ // they are all created using string literals.
if (name == knownLevels[i].name)
return knownLevels[i];
}
diff --git a/java/util/logging/LogManager.java b/java/util/logging/LogManager.java
index 73eb9bcdd..e2604815b 100644
--- a/java/util/logging/LogManager.java
+++ b/java/util/logging/LogManager.java
@@ -1,6 +1,6 @@
/* LogManager.java -- a class for maintaining Loggers and managing
configuration properties
- Copyright (C) 2002,2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,11 +48,14 @@ import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
+import gnu.classpath.SystemProperties;
+
/**
* The <code>LogManager</code> maintains a hierarchical namespace
* of Logger objects and manages properties for configuring the logging
@@ -114,7 +117,6 @@ public class LogManager
* a WeakReference to it.
*/
private Map loggers;
- final Logger rootLogger;
/**
* The properties for the logging framework which have been
@@ -135,83 +137,62 @@ public class LogManager
* this case.
*/
private final PropertyChangeSupport pcs = new PropertyChangeSupport( /* source bean */
- LogManager.class);
+ LogManager.class);
protected LogManager()
{
- if (logManager != null)
- throw new IllegalStateException("there can be only one LogManager; use LogManager.getLogManager()");
-
- logManager = this;
- loggers = new java.util.HashMap();
- rootLogger = new Logger("", null);
- rootLogger.setLevel(Level.INFO);
- addLogger(rootLogger);
-
- /* Make sure that Logger.global has the rootLogger as its parent.
- *
- * Logger.global is set during class initialization of Logger,
- * which may or may not be before this code is being executed.
- * For example, on the Sun 1.3.1 and 1.4.0 JVMs, Logger.global
- * has been set before this code is being executed. In contrast,
- * Logger.global still is null on GCJ 3.2. Since the LogManager
- * and Logger classes are mutually dependent, both behaviors are
- * correct.
- *
- * This means that we cannot depend on Logger.global to have its
- * value when this code executes, although that variable is final.
- * Since Logger.getLogger will always return the same logger for
- * the same name, the subsequent line works fine irrespective of
- * the order in which classes are initialized.
- */
- Logger.getLogger("global").setParent(rootLogger);
- Logger.getLogger("global").setUseParentHandlers(true);
+ loggers = new HashMap();
}
/**
* Returns the globally shared LogManager instance.
*/
- public static LogManager getLogManager()
+ public static synchronized LogManager getLogManager()
{
+ if (logManager == null)
+ {
+ logManager = makeLogManager();
+ initLogManager();
+ }
return logManager;
}
- static
- {
- makeLogManager();
-
- /* The Javadoc description of the class explains
- * what is going on here.
- */
- Object configurator = createInstance(System.getProperty("java.util.logging.config.class"),
- /* must be instance of */ Object.class);
-
- try
- {
- if (configurator == null)
- getLogManager().readConfiguration();
- }
- catch (IOException ex)
- {
- /* FIXME: Is it ok to ignore exceptions here? */
- }
- }
+ private static final String MANAGER_PROPERTY = "java.util.logging.manager";
private static LogManager makeLogManager()
{
- String managerClassName;
- LogManager manager;
+ String managerClassName = SystemProperties.getProperty(MANAGER_PROPERTY);
+ LogManager manager = (LogManager) createInstance
+ (managerClassName, LogManager.class, MANAGER_PROPERTY);
+ if (manager == null)
+ manager = new LogManager();
+ return manager;
+ }
- managerClassName = System.getProperty("java.util.logging.manager");
- manager = (LogManager) createInstance(managerClassName, LogManager.class);
- if (manager != null)
- return manager;
+ private static final String CONFIG_PROPERTY = "java.util.logging.config.class";
- if (managerClassName != null)
- System.err.println("WARNING: System property \"java.util.logging.manager\""
- + " should be the name of a subclass of java.util.logging.LogManager");
+ private static void initLogManager()
+ {
+ LogManager manager = getLogManager();
+ Logger.root.setLevel(Level.INFO);
+ manager.addLogger(Logger.root);
+
+ /* The Javadoc description of the class explains
+ * what is going on here.
+ */
+ Object configurator = createInstance(System.getProperty(CONFIG_PROPERTY),
+ /* must be instance of */ Object.class,
+ CONFIG_PROPERTY);
- return new LogManager();
+ try
+ {
+ if (configurator == null)
+ manager.readConfiguration();
+ }
+ catch (IOException ex)
+ {
+ /* FIXME: Is it ok to ignore exceptions here? */
+ }
}
/**
@@ -314,7 +295,7 @@ public class LogManager
if(index > -1)
searchName = searchName.substring(0,index);
else
- searchName = "";
+ searchName = "";
}
logger.setLevel(logLevel);
@@ -324,12 +305,12 @@ public class LogManager
* When adding "foo.bar", the logger "foo.bar.baz" should change
* its parent to "foo.bar".
*/
- if (parent != rootLogger)
+ if (parent != Logger.root)
{
for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();)
{
Logger possChild = (Logger) ((WeakReference) loggers.get(iter.next()))
- .get();
+ .get();
if ((possChild == null) || (possChild == logger)
|| (possChild.getParent() != parent))
continue;
@@ -367,14 +348,14 @@ public class LogManager
{
String childName = child.getName();
int childNameLength = childName.length();
- Logger best = rootLogger;
+ Logger best = Logger.root;
int bestNameLength = 0;
Logger cand;
String candName;
int candNameLength;
- if (child == rootLogger)
+ if (child == Logger.root)
return null;
for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();)
@@ -468,7 +449,7 @@ public class LogManager
if (logger == null)
iter.remove();
- else if (logger != rootLogger)
+ else if (logger != Logger.root)
{
logger.resetLogger();
logger.setLevel(null);
@@ -476,8 +457,8 @@ public class LogManager
}
}
- rootLogger.setLevel(Level.INFO);
- rootLogger.resetLogger();
+ Logger.root.setLevel(Level.INFO);
+ Logger.root.resetLogger();
}
/**
@@ -524,11 +505,11 @@ public class LogManager
// If no config file could be found use a default configuration.
if(inputStream == null)
- {
- String defaultConfig = "handlers = java.util.logging.ConsoleHandler \n"
+ {
+ String defaultConfig = "handlers = java.util.logging.ConsoleHandler \n"
+ ".level=INFO \n";
- inputStream = new ByteArrayInputStream(defaultConfig.getBytes());
- }
+ inputStream = new ByteArrayInputStream(defaultConfig.getBytes());
+ }
}
else
inputStream = new java.io.FileInputStream(path);
@@ -574,21 +555,9 @@ public class LogManager
while (tokenizer.hasMoreTokens())
{
String handlerName = tokenizer.nextToken();
- try
- {
- Class handlerClass = ClassLoader.getSystemClassLoader().loadClass(handlerName);
- getLogger("").addHandler((Handler) handlerClass
- .newInstance());
- }
- catch (ClassCastException ex)
- {
- System.err.println("[LogManager] class " + handlerName
- + " is not subclass of java.util.logging.Handler");
- }
- catch (Exception ex)
- {
- //System.out.println("[LogManager.readConfiguration]"+ex);
- }
+ Handler handler = (Handler)
+ createInstance(handlerName, Handler.class, key);
+ Logger.root.addHandler(handler);
}
}
@@ -602,14 +571,19 @@ public class LogManager
logger = Logger.getLogger(loggerName);
addLogger(logger);
}
+ Level level = null;
try
- {
- logger.setLevel(Level.parse(value));
- }
- catch (Exception _)
- {
- //System.out.println("[LogManager.readConfiguration] "+_);
- }
+ {
+ level = Level.parse(value);
+ }
+ catch (IllegalArgumentException e)
+ {
+ warn("bad level \'" + value + "\'", e);
+ }
+ if (level != null)
+ {
+ logger.setLevel(level);
+ }
continue;
}
}
@@ -748,19 +722,17 @@ public class LogManager
*/
static final Class getClassProperty(String propertyName, Class defaultValue)
{
- Class usingClass = null;
+ String propertyValue = logManager.getProperty(propertyName);
- try
- {
- String propertyValue = logManager.getProperty(propertyName);
- if (propertyValue != null)
- usingClass = Class.forName(propertyValue);
- if (usingClass != null)
- return usingClass;
- }
- catch (Exception _)
- {
- }
+ if (propertyValue != null)
+ try
+ {
+ return locateClass(propertyValue);
+ }
+ catch (ClassNotFoundException e)
+ {
+ warn(propertyName + " = " + propertyValue, e);
+ }
return defaultValue;
}
@@ -774,12 +746,17 @@ public class LogManager
try
{
- Object obj = klass.newInstance();
- if (ofClass.isInstance(obj))
- return obj;
+ Object obj = klass.newInstance();
+ if (ofClass.isInstance(obj))
+ return obj;
}
- catch (Exception _)
+ catch (InstantiationException e)
{
+ warn(propertyName + " = " + klass.getName(), e);
+ }
+ catch (IllegalAccessException e)
+ {
+ warn(propertyName + " = " + klass.getName(), e);
}
if (defaultClass == null)
@@ -824,14 +801,17 @@ public class LogManager
}
/**
- * Creates a new instance of a class specified by name.
+ * Creates a new instance of a class specified by name and verifies
+ * that it is an instance (or subclass of) a given type.
*
* @param className the name of the class of which a new instance
* should be created.
*
- * @param ofClass the class to which the new instance should
- * be either an instance or an instance of a subclass.
- * FIXME: This description is just terrible.
+ * @param type the object created must be an instance of
+ * <code>type</code> or any subclass of <code>type</code>
+ *
+ * @param property the system property to reference in error
+ * messages
*
* @return the new instance, or <code>null</code> if
* <code>className</code> is <code>null</code>, if no class
@@ -839,28 +819,89 @@ public class LogManager
* loading that class, or if the constructor of the class
* has thrown an exception.
*/
- static final Object createInstance(String className, Class ofClass)
+ private static final Object createInstance(String className, Class type,
+ String property)
{
- Class klass;
+ Class klass = null;
if ((className == null) || (className.length() == 0))
return null;
try
{
- klass = Class.forName(className);
- if (! ofClass.isAssignableFrom(klass))
- return null;
-
- return klass.newInstance();
+ klass = locateClass(className);
+ if (type.isAssignableFrom(klass))
+ return klass.newInstance();
+ warn(property, className, "not an instance of " + type.getName());
+ }
+ catch (ClassNotFoundException e)
+ {
+ warn(property, className, "class not found");
+ }
+ catch (IllegalAccessException e)
+ {
+ warn(property, className, "illegal access");
}
- catch (Exception _)
+ catch (InstantiationException e)
{
- return null;
+ warn(property, className, e);
}
- catch (java.lang.LinkageError _)
+ catch (java.lang.LinkageError e)
{
- return null;
+ warn(property, className, "linkage error");
}
+
+ return null;
}
+
+ private static final void warn(String property, String klass, Throwable t)
+ {
+ warn(property, klass, null, t);
+ }
+
+ private static final void warn(String property, String klass, String msg)
+ {
+ warn(property, klass, msg, null);
+ }
+
+ private static final void warn(String property, String klass, String msg,
+ Throwable t)
+ {
+ warn("error instantiating '" + klass + "' referenced by " + property +
+ (msg == null ? "" : ", " + msg), t);
+ }
+
+ /**
+ * All debug warnings go through this method.
+ */
+
+ private static final void warn(String msg, Throwable t)
+ {
+ System.err.println("WARNING: " + msg);
+ if (t != null)
+ t.printStackTrace(System.err);
+ }
+
+ /**
+ * Locates a class by first checking the system class loader and
+ * then checking the context class loader.
+ *
+ * @param name the fully qualified name of the Class to locate
+ * @return Class the located Class
+ */
+
+ private static Class locateClass(String name) throws ClassNotFoundException
+ {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ return Class.forName(name, true, loader);
+ }
+ catch (ClassNotFoundException e)
+ {
+ loader = ClassLoader.getSystemClassLoader();
+ return Class.forName(name, true, loader);
+ }
+ }
+
}
diff --git a/java/util/logging/Logger.java b/java/util/logging/Logger.java
index 367faad97..567020ef7 100644
--- a/java/util/logging/Logger.java
+++ b/java/util/logging/Logger.java
@@ -1,5 +1,5 @@
/* Logger.java -- a class for logging messages
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -67,6 +67,9 @@ import java.util.ResourceBundle;
*/
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
@@ -175,7 +178,7 @@ public class Logger
/* This is null when the root logger is being constructed,
* and the root logger afterwards.
*/
- parent = LogManager.getLogManager().rootLogger;
+ parent = root;
useParentHandlers = (parent != null);
}
@@ -1148,16 +1151,12 @@ public class Logger
*/
public synchronized void setParent(Logger parent)
{
- LogManager lm;
-
/* Throw a new NullPointerException if parent is null. */
parent.getClass();
- lm = LogManager.getLogManager();
-
- if (this == lm.rootLogger)
+ if (this == root)
throw new IllegalArgumentException(
- "only the root logger can have a null parent");
+ "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