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]