Author: skitching
Date: Sat Mar 12 20:20:38 2005
New Revision: 157309

URL: http://svn.apache.org/viewcvs?view=rev&rev=157309
Log:
Updated javadoc only.

Modified:
    
jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/ContextClassLoaderLocal.java

Modified: 
jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/ContextClassLoaderLocal.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/ContextClassLoaderLocal.java?view=diff&r1=157308&r2=157309
==============================================================================
--- 
jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/ContextClassLoaderLocal.java
 (original)
+++ 
jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/ContextClassLoaderLocal.java
 Sat Mar 12 20:20:38 2005
@@ -20,12 +20,81 @@
 import java.util.WeakHashMap;
 
 /**
- * A value that is provided per (thread) context classloader.
- * Patterned after ThreadLocal. 
- * There is a separate value used when Thread.getContextClassLoader() is null. 
 
- * This mechanism provides isolation for web apps deployed in the same 
container. 
- * <strong>Note:</strong> A WeakHashMap bug in several 1.3 JVMs results in a 
memory leak
- * for those JVMs.
+ * An instance of this class represents a value that is provided per (thread)
+ * context classloader.
+ * 
+ * <p>Occasionally it is necessary to store data in "global" variables
+ * (including uses of the Singleton pattern). In applications which have only
+ * a single classloader such data can simply be stored as "static" members on
+ * some class. When multiple classloaders are involved, however, this approach
+ * can fail; in particular, this doesn't work when the code may be run within a
+ * servlet container or a j2ee container, and the class on which the static
+ * member is defined is loaded via a "shared" classloader that is visible to 
all
+ * components running within the container. This class provides a mechanism for
+ * associating data with a ClassLoader instance, which ensures that when the
+ * code runs in such a container each component gets its own copy of the
+ * "global" variable rather than unexpectedly sharing a single copy of the
+ * variable with other components that happen to be running in the same
+ * container at the same time (eg servlets or EJBs.)</p>
+ *
+ * <p>This class is strongly patterned after the java.lang.ThreadLocal
+ * class, which performs a similar task in allowing data to be associated
+ * with a particular thread.</p>
+ *
+ * <p>When code that uses this class is run as a "normal" application, ie
+ * not within a container, the effect is identical to just using a static 
+ * member variable to store the data, because Thread.getContextClassLoader
+ * always returns the same classloader (the system classloader).</p>
+ *
+ * <p>Expected usage is as follows:<br>
+ * <pre>
+ *  public class SomeClass {
+ *    private static final ContextClassLoaderLocal global 
+ *      = new ContextClassLoaderLocal() {
+ *          protected Object initialValue() {
+ *              return new String("Initial value");
+ *          };
+ *
+ *    public void testGlobal() {
+ *      String s = (String) global.get();
+ *      System.out.println("global value:" + s);
+ *      buf.set("New Value");
+ *    }
+ * </pre>
+ * </p>
+ *
+ * <p><strong>Note:</strong> This class takes some care to ensure that when
+ * a component which uses this class is "undeployed" by a container the
+ * component-specific classloader and all its associated classes (and their
+ * static variables) are garbage-collected. Unfortunately there is one
+ * scenario in which this does <i>not</i> work correctly and there
+ * is unfortunately no known workaround other than ensuring that the
+ * component (or its container) calls the "unset" method on this class for
+ * each instance of this class when the component is undeployed. The problem
+ * occurs if:
+ * <ul>
+ * <li>the class containing a static instance of this class was loaded via
+ * a shared classloader, and</li>
+ * <li>the value stored in the instance is an object whose class was loaded
+ * via the component-specific classloader (or any of the objects it refers
+ * to were loaded via that classloader).</li>
+ * </ul>
+ * The result is that the map managed by this object still contains a strong
+ * reference to the stored object, which contains a strong reference to the
+ * classloader that loaded it, meaning that although the container has
+ * "undeployed" the component the component-specific classloader and all the
+ * related classes and static variables cannot be garbage-collected. This is
+ * not expected to be an issue with the commons-beanutils library as the only
+ * classes which use this class are BeanUtilsBean and ConvertUtilsBean and
+ * there is no obvious reason for a user of the beanutils library to subclass
+ * either of those classes.</p>
+ *
+ * <p><strong>Note:</strong> A WeakHashMap bug in several 1.3 JVMs results in 
+ * a memory leak for those JVMs.</p>
+ *
+ * <p><strong>Note:</strong> Of course all of this would be unnecessary if
+ * containers required each component to load the full set of classes it
+ * needs, ie avoided providing classes loaded via a "shared" classloader.</p>
  * 
  * @see java.lang.Thread#getContextClassLoader  
  * @author Eric Pabst
@@ -60,11 +129,11 @@
      * Gets the instance which provides the functionality for [EMAIL 
PROTECTED] BeanUtils}.
      * This is a pseudo-singleton - an single instance is provided per 
(thread) context classloader.
      * This mechanism provides isolation for web apps deployed in the same 
container. 
-     * @return the object currently associated with the 
+     * @return the object currently associated with the context-classloader of 
the current thread. 
      */
     public synchronized Object get() {
         // synchronizing the whole method is a bit slower 
-        // but guarentees no subtle threading problems, and there's no 
+        // but guarantees no subtle threading problems, and there's no 
         // need to synchronize valueByClassLoader
         
         // make sure that the map is given a change to purge itself



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to