From 6a315e28ed013f7c718eef292f3eade549151a55 Mon Sep 17 00:00:00 2001 From: "Craig R. McClanahan" Date: Thu, 14 Feb 2002 00:19:03 +0000 Subject: [PATCH] Improvements to the new LogFactory APIs, based on feedback from Costin and Jon plus some additional thought about using it in a multi-class-loader environment (like Tomcat): * Changed newFactory() to getFactory(), and implemented a cache of previously created factory instances (one per class loader). This avoids potentially expensive and redundant discovery operations. * Added convenient static getLog() method so a typical application component can initialize it's Log instance like this: Log log = LogFactory.getLog("com.mycompany.mypackage.MyClass"); * Added variants of getInstance() and getLog() that take a Class parameter instead of a String. LogSource had this convenience feature, and there's no reason not to keep it. * Added release() and releaseAll() methods to instruct the factory instances to release any cached references to other LogFactory or Log instances. This is important, for example, if you put commons-logging.jar in Tomcat's shared "lib" directory, and then use the application reload facility. The references maintained here would otherwise prevent garbage collection of the old webapp class loader once a reload takes place. * Added a note on getInstance() that you can make no assumptions about whether or not the actual Log instance you get back is shared or not. The actual sharability is a feature of the LogFactory implementation you are using, and what kind of a class loader environment you ae installing. * Deprecated LogSource, but left it there to ease transition of existing code using it. git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/logging/trunk@138858 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/commons/logging/LogFactory.java | 172 ++++++++++++++---- .../org/apache/commons/logging/LogSource.java | 11 +- .../commons/logging/impl/LogFactoryImpl.java | 45 ++++- 3 files changed, 189 insertions(+), 39 deletions(-) diff --git a/src/java/org/apache/commons/logging/LogFactory.java b/src/java/org/apache/commons/logging/LogFactory.java index badf32d..14f63e4 100644 --- a/src/java/org/apache/commons/logging/LogFactory.java +++ b/src/java/org/apache/commons/logging/LogFactory.java @@ -1,7 +1,7 @@ /* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//logging/src/java/org/apache/commons/logging/LogFactory.java,v 1.1 2002/02/13 02:18:11 craigmcc Exp $ - * $Revision: 1.1 $ - * $Date: 2002/02/13 02:18:11 $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//logging/src/java/org/apache/commons/logging/LogFactory.java,v 1.2 2002/02/14 00:19:03 craigmcc Exp $ + * $Revision: 1.2 $ + * $Date: 2002/02/14 00:19:03 $ * * ==================================================================== * @@ -67,6 +67,7 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Enumeration; +import java.util.Hashtable; import java.util.Properties; @@ -81,7 +82,7 @@ import java.util.Properties; * * @author Craig R. McClanahan * @author Costin Manolache - * @version $Revision: 1.1 $ $Date: 2002/02/13 02:18:11 $ + * @version $Revision: 1.2 $ $Date: 2002/02/14 00:19:03 $ */ public abstract class LogFactory { @@ -142,10 +143,29 @@ public abstract class LogFactory { public abstract String[] getAttributeNames(); + /** + * Convenience method to derive a name from the specified class and + * call getInstance(String) with it. + * + * @param clazz Class for which a suitable Log name will be derived + * + * @exception LogConfigurationException if a suitable Log + * instance cannot be returned + */ + public abstract Log getInstance(Class clazz) + throws LogConfigurationException; + + /** *

Construct (if necessary) and return a Log instance, * using the factory's current set of configuration attributes.

* + *

NOTE - Depending upon the implementation of + * the LogFactory you are using, the Log + * instance you are returned may or may not be local to the current + * application, and may or may not be returned again on a subsequent + * call with the same name argument.

+ * * @param name Logical name of the Log instance to be * returned (the meaning of this name is only known to the underlying * logging implementation that is being wrapped) @@ -157,6 +177,16 @@ public abstract class LogFactory { throws LogConfigurationException; + /** + * Release any internal references to previously created {@link Log} + * instances returned by this factory. This is useful environments + * like servlet containers, which implement application reloading by + * throwing away a ClassLoader. Dangling references to objects in that + * class loader would prevent garbage collection. + */ + public abstract void release(); + + /** * Remove any configuration attribute associated with the specified name. * If there is no such attribute, no action is taken. @@ -178,13 +208,23 @@ public abstract class LogFactory { public abstract void setAttribute(String name, Object value); + // ------------------------------------------------------- Static Variables + + + /** + * The previously constructed LogFactory instances, keyed by + * the ClassLoader with which it was created. + */ + protected static Hashtable factories = new Hashtable(); + + // --------------------------------------------------------- Static Methods /** - *

Construct and return a new LogFactory instance, using - * the following ordered lookup procedure to determine the name of the - * implementation class to be loaded:

+ *

Construct (if necessary) and return a LogFactory + * instance, using the following ordered lookup procedure to determine + * the name of the implementation class to be loaded:

* * + * @deprecated Use {@link LogFactory} instead - The default factory + * implementation performs exactly the same algorithm as this class did + * * @author Rod Waldhoff - * @version $Id: LogSource.java,v 1.12 2002/02/03 01:31:54 sanders Exp $ + * @version $Id: LogSource.java,v 1.13 2002/02/14 00:19:03 craigmcc Exp $ */ public class LogSource { diff --git a/src/java/org/apache/commons/logging/impl/LogFactoryImpl.java b/src/java/org/apache/commons/logging/impl/LogFactoryImpl.java index b32036f..5440310 100644 --- a/src/java/org/apache/commons/logging/impl/LogFactoryImpl.java +++ b/src/java/org/apache/commons/logging/impl/LogFactoryImpl.java @@ -1,7 +1,7 @@ /* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//logging/src/java/org/apache/commons/logging/impl/LogFactoryImpl.java,v 1.1 2002/02/13 02:18:11 craigmcc Exp $ - * $Revision: 1.1 $ - * $Date: 2002/02/13 02:18:11 $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//logging/src/java/org/apache/commons/logging/impl/LogFactoryImpl.java,v 1.2 2002/02/14 00:19:03 craigmcc Exp $ + * $Revision: 1.2 $ + * $Date: 2002/02/14 00:19:03 $ * * ==================================================================== * @@ -101,7 +101,7 @@ import org.apache.commons.logging.LogSource; * * @author Rod Waldhoff * @author Craig R. McClanahan - * @version $Revision: 1.1 $ $Date: 2002/02/13 02:18:11 $ + * @version $Revision: 1.2 $ $Date: 2002/02/14 00:19:03 $ */ public class LogFactoryImpl extends LogFactory { @@ -228,10 +228,33 @@ public class LogFactoryImpl extends LogFactory { } + /** + * Convenience method to derive a name from the specified class and + * call getInstance(String) with it. + * + * @param clazz Class for which a suitable Log name will be derived + * + * @exception LogConfigurationException if a suitable Log + * instance cannot be returned + */ + public Log getInstance(Class clazz) + throws LogConfigurationException { + + return (getInstance(clazz.getName())); + + } + + /** *

Construct (if necessary) and return a Log instance, * using the factory's current set of configuration attributes.

* + *

NOTE - Depending upon the implementation of + * the LogFactory you are using, the Log + * instance you are returned may or may not be local to the current + * application, and may or may not be returned again on a subsequent + * call with the same name argument.

+ * * @param name Logical name of the Log instance to be * returned (the meaning of this name is only known to the underlying * logging implementation that is being wrapped) @@ -252,6 +275,20 @@ public class LogFactoryImpl extends LogFactory { } + /** + * Release any internal references to previously created {@link Log} + * instances returned by this factory. This is useful environments + * like servlet containers, which implement application reloading by + * throwing away a ClassLoader. Dangling references to objects in that + * class loader would prevent garbage collection. + */ + public void release() { + + instances.clear(); + + } + + /** * Remove any configuration attribute associated with the specified name. * If there is no such attribute, no action is taken.