From 52965614744fca2bee6cad3ddac853e910c3cd84 Mon Sep 17 00:00:00 2001 From: kkolinko Date: Fri, 12 Feb 2010 03:19:31 +0000 Subject: [PATCH] When the key is null (i.e., a stale entry), it cannot be removed with an explicit remove(key) call: you'll get an NPE. Those can be removed with expungeStaleEntries() call. 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 --- .../org/apache/catalina/loader/WebappClassLoader.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/java/org/apache/catalina/loader/WebappClassLoader.java b/java/org/apache/catalina/loader/WebappClassLoader.java index 37d87d2a5..4e98b1bfa 100644 --- a/java/org/apache/catalina/loader/WebappClassLoader.java +++ b/java/org/apache/catalina/loader/WebappClassLoader.java @@ -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); + } } } -- 2.11.0