Author: markt
Date: Thu Apr 19 20:19:12 2007
New Revision: 530625

URL: http://svn.apache.org/viewvc?view=rev&rev=530625
Log:
Fix bug 41939 by porting the TC6 configuration option for clearing static and 
final fields from loaded classes.

Modified:
    
tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java
    tomcat/container/tc5.5.x/webapps/docs/changelog.xml

Modified: 
tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java
URL: 
http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java?view=diff&rev=530625&r1=530624&r2=530625
==============================================================================
--- 
tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java
 (original)
+++ 
tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java
 Thu Apr 19 20:19:12 2007
@@ -112,6 +112,9 @@
     protected static org.apache.commons.logging.Log log=
         org.apache.commons.logging.LogFactory.getLog( WebappClassLoader.class 
);
 
+    public static final boolean ENABLE_CLEAR_REFERENCES = 
+        
Boolean.valueOf(System.getProperty("org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES",
 "true")).booleanValue();
+
     protected class PrivilegedFindResource
         implements PrivilegedAction {
 
@@ -1589,46 +1592,48 @@
         
         // Null out any static or final fields from loaded classes,
         // as a workaround for apparent garbage collection bugs
-        Iterator loadedClasses = ((HashMap) 
resourceEntries.clone()).values().iterator();
-        while (loadedClasses.hasNext()) {
-            ResourceEntry entry = (ResourceEntry) loadedClasses.next();
-            if (entry.loadedClass != null) {
-                Class clazz = entry.loadedClass;
-                try {
-                    Field[] fields = clazz.getDeclaredFields();
-                    for (int i = 0; i < fields.length; i++) {
-                        Field field = fields[i];
-                        int mods = field.getModifiers();
-                        if (field.getType().isPrimitive() 
-                                || (field.getName().indexOf("$") != -1)) {
-                            continue;
-                        }
-                        if (Modifier.isStatic(mods)) {
-                            try {
-                                field.setAccessible(true);
-                                if (Modifier.isFinal(mods)) {
-                                    if 
(!((field.getType().getName().startsWith("java."))
-                                            || 
(field.getType().getName().startsWith("javax.")))) {
-                                        nullInstance(field.get(null));
+        if (ENABLE_CLEAR_REFERENCES) {
+            Iterator loadedClasses = ((HashMap) 
resourceEntries.clone()).values().iterator();
+            while (loadedClasses.hasNext()) {
+                ResourceEntry entry = (ResourceEntry) loadedClasses.next();
+                if (entry.loadedClass != null) {
+                    Class clazz = entry.loadedClass;
+                    try {
+                        Field[] fields = clazz.getDeclaredFields();
+                        for (int i = 0; i < fields.length; i++) {
+                            Field field = fields[i];
+                            int mods = field.getModifiers();
+                            if (field.getType().isPrimitive() 
+                                    || (field.getName().indexOf("$") != -1)) {
+                                continue;
+                            }
+                            if (Modifier.isStatic(mods)) {
+                                try {
+                                    field.setAccessible(true);
+                                    if (Modifier.isFinal(mods)) {
+                                        if 
(!((field.getType().getName().startsWith("java."))
+                                                || 
(field.getType().getName().startsWith("javax.")))) {
+                                            nullInstance(field.get(null));
+                                        }
+                                    } else {
+                                        field.set(null, null);
+                                        if (log.isDebugEnabled()) {
+                                            log.debug("Set field " + 
field.getName() 
+                                                    + " to null in class " + 
clazz.getName());
+                                        }
                                     }
-                                } else {
-                                    field.set(null, null);
+                                } catch (Throwable t) {
                                     if (log.isDebugEnabled()) {
-                                        log.debug("Set field " + 
field.getName() 
-                                                + " to null in class " + 
clazz.getName());
+                                        log.debug("Could not set field " + 
field.getName() 
+                                                + " to null in class " + 
clazz.getName(), t);
                                     }
                                 }
-                            } catch (Throwable t) {
-                                if (log.isDebugEnabled()) {
-                                    log.debug("Could not set field " + 
field.getName() 
-                                            + " to null in class " + 
clazz.getName(), t);
-                                }
                             }
                         }
-                    }
-                } catch (Throwable t) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("Could not clean fields for class " + 
clazz.getName(), t);
+                    } catch (Throwable t) {
+                        if (log.isDebugEnabled()) {
+                            log.debug("Could not clean fields for class " + 
clazz.getName(), t);
+                        }
                     }
                 }
             }

Modified: tomcat/container/tc5.5.x/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/webapps/docs/changelog.xml?view=diff&rev=530625&r1=530624&r2=530625
==============================================================================
--- tomcat/container/tc5.5.x/webapps/docs/changelog.xml (original)
+++ tomcat/container/tc5.5.x/webapps/docs/changelog.xml Thu Apr 19 20:19:12 2007
@@ -60,6 +60,13 @@
         <bug>41655</bug> Fix message translations. Japanese translations
         provided by Suzuki Yuichiro. (markt)
       </fix>
+      <fix>
+        <bug>41939</bug> Add configuration option to disable nulling of static
+        and final fields of loaded classes when stopping a web application
+        classloader. Setting the system property
+        org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES to
+        false will stop these fields being set to null on context stop. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Webapps">



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

Reply via email to