When the key is null (i.e., a stale entry), it cannot be removed with an explicit...
authorkkolinko <kkolinko@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 12 Feb 2010 03:19:31 +0000 (03:19 +0000)
committerkkolinko <kkolinko@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 12 Feb 2010 03:19:31 +0000 (03:19 +0000)
Also, simplified the code: Reference.referent can be accessed by calling get() - no need to use reflection for that.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@909212 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/loader/WebappClassLoader.java

index 37d87d2..4e98b1b 100644 (file)
@@ -2177,15 +2177,13 @@ public class WebappClassLoader
                         ThreadLocal.class);
             mapRemove.setAccessible(true);
             Object[] table = (Object[]) internalTableField.get(map);
+            int staleEntriesCount = 0;
             if (table != null) {
                 for (int j =0; j < table.length; j++) {
                     if (table[j] != null) {
                         boolean remove = false;
                         // Check the key
-                        Field keyField =
-                            Reference.class.getDeclaredField("referent");
-                        keyField.setAccessible(true);
-                        Object key = keyField.get(table[j]);
+                        Object key = ((Reference<?>) table[j]).get();
                         if (this.equals(key) || (key != null &&
                                 this == key.getClass().getClassLoader())) {
                             remove = true;
@@ -2200,7 +2198,6 @@ public class WebappClassLoader
                             remove = true;
                         }
                         if (remove) {
-                            Object entry = ((Reference<?>) table[j]).get();
                             Object[] args = new Object[4];
                             if (key != null) {
                                 args[0] = key.getClass().getCanonicalName();
@@ -2221,11 +2218,21 @@ public class WebappClassLoader
                                         "webappClassLoader.clearThreadLocal",
                                         args));
                             }
-                            mapRemove.invoke(map, entry);
+                            if (key == null) {
+                              staleEntriesCount++;
+                            } else {
+                              mapRemove.invoke(map, key);
+                            }
                         }
                     }
                 }
             }
+            if (staleEntriesCount > 0) {
+                Method mapRemoveStale =
+                    map.getClass().getDeclaredMethod("expungeStaleEntries");
+                mapRemoveStale.setAccessible(true);
+                mapRemoveStale.invoke(map);
+            }
         }
     }