Author: remm
Date: Thu Nov 17 04:10:48 2005
New Revision: 345233

URL: http://svn.apache.org/viewcvs?rev=345233&view=rev
Log:
- Fix NPE and exception problems with setting fields to null.

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

Modified: 
tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java
URL: 
http://svn.apache.org/viewcvs/tomcat/container/tc5.5.x/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java?rev=345233&r1=345232&r2=345233&view=diff
==============================================================================
--- 
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 Nov 17 04:10:48 2005
@@ -1571,24 +1571,46 @@
         
         // Null out any static or final fields from loaded classes,
         // as a workaround for apparent garbage collection bugs
-        Iterator loadedClasses = resourceEntries.values().iterator();
+        Iterator loadedClasses = ((HashMap) 
resourceEntries.clone()).values().iterator();
         while (loadedClasses.hasNext()) {
             ResourceEntry entry = (ResourceEntry) loadedClasses.next();
             if (entry.loadedClass != null) {
-                Field[] fields = entry.loadedClass.getDeclaredFields();
-                for (int i = 0; i < fields.length; i++) {
-                    Field field = fields[i];
-                    int mods = field.getModifiers();
-                    if (!(!Modifier.isStatic(mods) || !Modifier.isFinal(mods) 
-                            || field.getType().isPrimitive() 
-                            || field.getName().indexOf("$") != -1)) {
-                        field.setAccessible(true);
-                        try {
-                            field.set(null, null);
-                        } catch (Exception e) {
-                            log.info("Could not set field " + field.getName() 
-                                    + " to null in class " + 
entry.loadedClass.getName(), e);
+                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());
+                                    }
+                                }
+                            } 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);
                     }
                 }
             }
@@ -1603,6 +1625,41 @@
         // Clear the classloader reference in the VM's bean introspector
         java.beans.Introspector.flushCaches();
 
+    }
+
+
+    protected void nullInstance(Object instance) {
+        if (instance == null) {
+            return;
+        }
+        Field[] fields = instance.getClass().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;
+            }
+            try {
+                field.setAccessible(true);
+                if (Modifier.isStatic(mods) && Modifier.isFinal(mods)) {
+                    // Doing something recursively is too risky
+                    continue;
+                } else {
+                    field.set(instance, null);
+                    if (log.isDebugEnabled()) {
+                        log.debug("Set field " + field.getName() 
+                                + " to null in class " + 
instance.getClass().getName());
+                    }
+                }
+            } catch (Throwable t) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Could not set field " + field.getName() 
+                            + " to null in object instance of class " 
+                            + instance.getClass().getName(), t);
+                }
+            }
+        }
     }
     
 



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

Reply via email to