From 6cf8566f8e2c722c338ea165c21da48fb5ab31a7 Mon Sep 17 00:00:00 2001 From: markt Date: Fri, 1 Oct 2010 11:10:51 +0000 Subject: [PATCH] Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49667 Ensure JDBC leak prevention code doesn't trigger the very memory leak it is meant to be fixing. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1003481 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/catalina/loader/JdbcLeakPrevention.java | 22 ++++++++++++++++++++-- webapps/docs/changelog.xml | 5 +++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/java/org/apache/catalina/loader/JdbcLeakPrevention.java b/java/org/apache/catalina/loader/JdbcLeakPrevention.java index 6f10dc8ca..48b2668e8 100644 --- a/java/org/apache/catalina/loader/JdbcLeakPrevention.java +++ b/java/org/apache/catalina/loader/JdbcLeakPrevention.java @@ -23,6 +23,7 @@ import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashSet; import java.util.List; /** @@ -41,16 +42,33 @@ public class JdbcLeakPrevention { public List clearJdbcDriverRegistrations() throws SQLException { List driverNames = new ArrayList(); - // This will list all drivers visible to this class loader + /* + * DriverManager.getDrivers() has a nasty side-effect of registering + * drivers that are visible to this class loader but haven't yet been + * loaded. Therefore, the first call to this method a) gets the list + * of originally loaded drivers and b) triggers the unwanted + * side-effect. The second call gets the complete list of drivers + * ensuring that both original drivers and any loaded as a result of the + * side-effects are all de-registered. + */ + HashSet originalDrivers = new HashSet(); Enumeration drivers = DriverManager.getDrivers(); while (drivers.hasMoreElements()) { + originalDrivers.add(drivers.nextElement()); + } + drivers = DriverManager.getDrivers(); + while (drivers.hasMoreElements()) { Driver driver = drivers.nextElement(); // Only unload the drivers this web app loaded if (driver.getClass().getClassLoader() != this.getClass().getClassLoader()) { continue; } - driverNames.add(driver.getClass().getCanonicalName()); + // Only report drivers that were originally registered. Skip any + // that were registered as a side-effect of this code. + if (originalDrivers.contains(driver)) { + driverNames.add(driver.getClass().getCanonicalName()); + } DriverManager.deregisterDriver(driver); } return driverNames; diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index fb838e5cb..4fbcd4f94 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -66,6 +66,11 @@ (markt) + 49667: Ensure that using the JDBC driver memory leak + prevention code does not cause a one of the memory leaks it is meant to + avoid. (markt) + + 49670: Restore SSO functionality that was broken by Lifecycle refactoring. (markt) -- 2.11.0