diff --git a/xdocs/guide.xml b/xdocs/guide.xml index b17d7ae..3e2936c 100644 --- a/xdocs/guide.xml +++ b/xdocs/guide.xml @@ -42,6 +42,13 @@
+The commons-logging.jar file includes the JCL API, the default
+LogFactory implemenation and thin-wrapper Log
+implementations for
+Log4J,
+Avalon LogKit,
+the Avalon Framework's logging infrastructure,
+JDK 1.4, as well as an implementation of JDK 1.4 logging APIs (JSR-47) for
+pre-1.4 systems.
+
+In most cases, including commons-logging.jar and your preferred
+logging implementation in the classpath should be all that is required to
+use JCL.
+
+The optional jar includes, oddly enough, optional classes that are useful but
+not strictly required to make JCL functional. As these classes introduce
+dependencies on JDK 1.3+ JVMs and a goal of JCL is to be usable on JDK 1.2
+and earlier JVMs, these optional classes are not included in the main
+commons-logging.jar.
+
+Included in the optional jar are classes which allow JCL to (potentially) improve
+it's memory utilization (see
+Classloader and Memory Management
+below). It is therefore recommended that (when running on a 1.3+ JDK) the optional jar
+be deployed alongside the
+main commons-logging.jar. It should be deployed such that it will be loaded
+by the same classloader that loads LogFactory. When so deployed, JCL will
+discover the appropriate classes and configure itself to use them.
+
+The commons-logging-api.jar file includes the JCL API and the
+default LogFactory implementation, but does not include the
+wrapper Log implementations for Log4j,
+Avalon and Lumberjack. This jar is intended for
+use in specialized containers such as
+Tomcat that wish to use
+JCL internally but also need to make JCL available for use by deployed
+applications.
+
+ If this jar is used, in order to benefit from improved memory management in modern JVMs (1.3+),
+ it is recommended that the commons-logging-optional.jar is deployed in
+ the same classloader as this jar.
+
@@ -501,6 +564,77 @@ Perhaps more direct support for internationalizing log messages
can be introduced in a future or alternate version of the Log interface.
+The LogFactory discovery process (see
+Configuration above) is a fairly expensive
+operation, so JCL certainly should not perform it each time user code
+invokes:
+
+Instead JCL caches the
+LogFactory implementation created as a result of the discovery
+process and uses the cached factory to return Log objects.
+Since in J2EE and similar multi-classloader environments, the result of the
+discovery process can vary depending on the thread context classloader
+(e.g. one webapp in a web container may be configured to use Log4j and
+another to use JDK 1.4 logging), JCL internally caches the
+LogFactory instances in a static hashtable, keyed by classloader.
+
+While this approach is efficient, it can lead to memory leaks if container +implementors are not careful to call +
+
+whenever a classloader that has utilized JCL is undeployed. If
+release() is not called, a reference to the undeployed
+classloader (and thus to all the classes loaded by it) will be
+held in LogFactory's static hashtable.
+
+Beginning with JCL 1.0.5, LogFactory will attempt to cache factory
+implementations in a
+WeakHashtable.
+This class is analogous to java.util.WeakHashMap in that it holds
+WeakReferences to its keys, thus allowing classloaders to be GC'd
+even if LogFactory.release() is never invoked.
+
+Because WeakHashtable depends on JDK 1.3+ features, it cannot
+be included in the main commons-logging.jar file. It is found
+in commons-logging-optional.jar. J2EE container
+implementors who distribute JCL with their application are strongly
+encouraged to place commons-logging-optional.jar on the classpath
+in the same location where LogFactory is loaded.
+
+In a particular usage scenario, WeakHashtable alone will
+be insufficent to allow garbage collection of a classloader without a call to
+release. If the abstract class LogFactory is
+loaded by a parent classloader and a concrete subclass implementation of
+LogFactory is loaded by a child classloader, the concrete
+implementation will have a strong reference to the child classloader via the
+chain getClass().getClassLoader(). The WeakHashtable
+will have a strong reference to the LogFactory implementation as
+one of the values in its map. This chain of references will prevent
+collection of the child classloader.
+
+Such a situation would typically only occur if commons-logging.jar were
+loaded by a parent classloader (e.g. a server level classloader in a
+servlet container) and a custom LogFactory implementation were
+loaded by a child classloader (e.g. a web app classloader). If use of
+a custom LogFactory subclass is desired, ensuring that the
+custom subclass is loaded by the same classloader as LogFactory
+will prevent problems. In normal deployments, the standard implementations
+of LogFactory found in package org.apache.commons.logging.impl
+will be loaded by the same classloader that loads LogFactory
+itself, so use of the standard LogFactory implementation
+should not pose problems.
+