From 2a4af57e197a0bced170e795b1c47892092d4322 Mon Sep 17 00:00:00 2001 From: songqingqing Date: Thu, 19 Apr 2018 10:40:22 +0800 Subject: [PATCH 01/16] modify DriverManagerCleanUp Add getAllDrivers method. DriverManager.getDrivers() only return the drivers which be load by caller(DriverManagerCleanUp.class). For many scenarios the Caller is not the same classloader which load the jdbc Drivers --- .../cleanup/DriverManagerCleanUp.java | 113 ++++++++++++------ 1 file changed, 75 insertions(+), 38 deletions(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java index 0b4787f0..b5b673ea 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java +++ b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java @@ -1,38 +1,75 @@ -package se.jiderhamn.classloader.leak.prevention.cleanup; - -import java.sql.Driver; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; - -import se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor; -import se.jiderhamn.classloader.leak.prevention.ClassLoaderPreMortemCleanUp; - -/** - * Deregister JDBC drivers loaded by classloader - * @author Mattias Jiderhamn - */ -public class DriverManagerCleanUp implements ClassLoaderPreMortemCleanUp { - @Override - public void cleanUp(ClassLoaderLeakPreventor preventor) { - final List driversToDeregister = new ArrayList(); - final Enumeration allDrivers = DriverManager.getDrivers(); - while(allDrivers.hasMoreElements()) { - final Driver driver = allDrivers.nextElement(); - if(preventor.isLoadedInClassLoader(driver)) // Should be true for all returned by DriverManager.getDrivers() - driversToDeregister.add(driver); - } - - for(Driver driver : driversToDeregister) { - try { - preventor.warn("JDBC driver loaded by protected ClassLoader deregistered: " + driver.getClass()); - DriverManager.deregisterDriver(driver); - } - catch (SQLException e) { - preventor.error(e); - } - } - } -} \ No newline at end of file +package se.jiderhamn.classloader.leak.prevention.cleanup; + +import java.lang.reflect.Field; +import java.sql.Driver; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor; +import se.jiderhamn.classloader.leak.prevention.ClassLoaderPreMortemCleanUp; + +/** + * Deregister JDBC drivers loaded by classloader + * + * + * @author Mattias Jiderhamn + * @author SONGQQ 2018-4-19 + * + */ +public class DriverManagerCleanUp implements ClassLoaderPreMortemCleanUp { + @Override + public void cleanUp(ClassLoaderLeakPreventor preventor) { + final List driversToDeregister = new ArrayList(); + final Enumeration allDrivers = getAllDrivers(preventor); + while (allDrivers.hasMoreElements()) { + final Driver driver = allDrivers.nextElement(); + if (preventor.isLoadedInClassLoader(driver)) // Should be true for all returned by DriverManager.getDrivers() + driversToDeregister.add(driver); + } + + for (Driver driver : driversToDeregister) { + try { + preventor.warn("JDBC driver loaded by protected ClassLoader deregistered: " + driver.getClass()); + DriverManager.deregisterDriver(driver); + } + catch (SQLException e) { + preventor.error(e); + } + } + } + + /** + * add getAllDrivers method. DriverManager.getDrivers() only return the drivers which be load by caller(DriverManagerCleanUp.class). + * For many scenarios the Caller is not the same classloader which load the jdbc Drivers + * + * @param preventor + * @return + */ + @SuppressWarnings("unchecked") + public java.util.Enumeration getAllDrivers(ClassLoaderLeakPreventor preventor) { + java.util.Vector result = new java.util.Vector(); + try { + Field registeredDrivers = DriverManager.class.getDeclaredField("registeredDrivers"); + registeredDrivers.setAccessible(true); + CopyOnWriteArrayList driverinfos = (CopyOnWriteArrayList) registeredDrivers.get(null); + + for (Object driverinfo : driverinfos) { + Field FDriver = driverinfo.getClass().getDeclaredField("driver"); + FDriver.setAccessible(true); + Driver driver = (Driver) FDriver.get(driverinfo); + result.addElement(driver); + } + } + catch (Exception e) { + preventor.warn("get All registeredDrivers Exception "); + preventor.error(e); + + } + return (result.elements()); + + } +} From 899feb3294143b48bf2699fdd3194821ccc459a3 Mon Sep 17 00:00:00 2001 From: songqingqing Date: Thu, 19 Apr 2018 12:46:28 +0800 Subject: [PATCH 02/16] refactor DriverManagerCleanUp --- .../leak/prevention/cleanup/DriverManagerCleanUp.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java index b5b673ea..58fa7774 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java +++ b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java @@ -1,6 +1,5 @@ package se.jiderhamn.classloader.leak.prevention.cleanup; -import java.lang.reflect.Field; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; @@ -49,18 +48,12 @@ public void cleanUp(ClassLoaderLeakPreventor preventor) { * @param preventor * @return */ - @SuppressWarnings("unchecked") public java.util.Enumeration getAllDrivers(ClassLoaderLeakPreventor preventor) { java.util.Vector result = new java.util.Vector(); try { - Field registeredDrivers = DriverManager.class.getDeclaredField("registeredDrivers"); - registeredDrivers.setAccessible(true); - CopyOnWriteArrayList driverinfos = (CopyOnWriteArrayList) registeredDrivers.get(null); - + CopyOnWriteArrayList driverinfos = preventor.getStaticFieldValue(DriverManager.class, "registeredDrivers"); for (Object driverinfo : driverinfos) { - Field FDriver = driverinfo.getClass().getDeclaredField("driver"); - FDriver.setAccessible(true); - Driver driver = (Driver) FDriver.get(driverinfo); + Driver driver = (Driver) preventor.getFieldValue(driverinfo, "driver"); result.addElement(driver); } } From 27e200d7901d0f458c4a45473ffdc799dbc0f3c8 Mon Sep 17 00:00:00 2001 From: songqingqing Date: Thu, 19 Apr 2018 15:37:17 +0800 Subject: [PATCH 03/16] refactor code modify code style; return DriverManager.getDrivers() if Exception occurred --- .../cleanup/DriverManagerCleanUp.java | 84 +++++++++---------- 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java index 58fa7774..6080ff85 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java +++ b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java @@ -5,64 +5,56 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Enumeration; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.Vector; import se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor; import se.jiderhamn.classloader.leak.prevention.ClassLoaderPreMortemCleanUp; /** * Deregister JDBC drivers loaded by classloader - * - * * @author Mattias Jiderhamn * @author SONGQQ 2018-4-19 - * */ public class DriverManagerCleanUp implements ClassLoaderPreMortemCleanUp { - @Override - public void cleanUp(ClassLoaderLeakPreventor preventor) { - final List driversToDeregister = new ArrayList(); - final Enumeration allDrivers = getAllDrivers(preventor); - while (allDrivers.hasMoreElements()) { - final Driver driver = allDrivers.nextElement(); - if (preventor.isLoadedInClassLoader(driver)) // Should be true for all returned by DriverManager.getDrivers() - driversToDeregister.add(driver); - } - - for (Driver driver : driversToDeregister) { - try { - preventor.warn("JDBC driver loaded by protected ClassLoader deregistered: " + driver.getClass()); - DriverManager.deregisterDriver(driver); - } - catch (SQLException e) { - preventor.error(e); - } - } - } - - /** - * add getAllDrivers method. DriverManager.getDrivers() only return the drivers which be load by caller(DriverManagerCleanUp.class). - * For many scenarios the Caller is not the same classloader which load the jdbc Drivers - * - * @param preventor - * @return - */ - public java.util.Enumeration getAllDrivers(ClassLoaderLeakPreventor preventor) { - java.util.Vector result = new java.util.Vector(); + @Override + public void cleanUp(ClassLoaderLeakPreventor preventor) { + final Enumeration allDrivers = getAllDrivers(preventor); + while (allDrivers.hasMoreElements()) { + final Driver driver = allDrivers.nextElement(); + if (preventor.isLoadedInClassLoader(driver)) { try { - CopyOnWriteArrayList driverinfos = preventor.getStaticFieldValue(DriverManager.class, "registeredDrivers"); - for (Object driverinfo : driverinfos) { - Driver driver = (Driver) preventor.getFieldValue(driverinfo, "driver"); - result.addElement(driver); - } - } - catch (Exception e) { - preventor.warn("get All registeredDrivers Exception "); - preventor.error(e); - + preventor.warn("JDBC driver loaded by protected ClassLoader deregistered: " + driver.getClass()); + DriverManager.deregisterDriver(driver); + } catch (SQLException e) { + preventor.error(e); } - return (result.elements()); + } + } + } + /** + * Add getAllDrivers method. DriverManager.getDrivers() only return the drivers + * which be load by caller(DriverManagerCleanUp.class). For many scenarios the + * caller is not the same classloader which load the jdbc drivers. + * @param preventor + * @return All drivers in DriverManager's registeredDrivers field,or + * DriverManager.getDrivers() if exception occurred + */ + public Enumeration getAllDrivers(ClassLoaderLeakPreventor preventor) { + Vector result = new java.util.Vector(); + try { + ArrayList driverinfos = preventor.getStaticFieldValue(DriverManager.class, "registeredDrivers"); + for (Object driverinfo : driverinfos) { + Driver driver = (Driver) preventor.getFieldValue(driverinfo, "driver"); + if (driver == null) + throw new NullPointerException(); + else + result.addElement(driver); + } + } catch (Exception e) { + preventor.warn("get All registeredDrivers Exception"); + return DriverManager.getDrivers(); } + return result.elements(); + } } From 3d91e47b875ec4b6870c13b56993b5679a1b3e85 Mon Sep 17 00:00:00 2001 From: songqingqing Date: Sat, 28 Apr 2018 18:25:29 +0800 Subject: [PATCH 04/16] bugfix reflection to do the DriverManager.deregisterDriver --- .../cleanup/DriverManagerCleanUp.java | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java index 6080ff85..e698f6f0 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java +++ b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java @@ -1,10 +1,14 @@ package se.jiderhamn.classloader.leak.prevention.cleanup; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.sql.Driver; +import java.sql.DriverAction; import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList; import java.util.Enumeration; +import java.util.List; import java.util.Vector; import se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor; @@ -24,8 +28,8 @@ public void cleanUp(ClassLoaderLeakPreventor preventor) { if (preventor.isLoadedInClassLoader(driver)) { try { preventor.warn("JDBC driver loaded by protected ClassLoader deregistered: " + driver.getClass()); - DriverManager.deregisterDriver(driver); - } catch (SQLException e) { + deregisterDriver(preventor, driver); + } catch (Exception e) { preventor.error(e); } } @@ -57,4 +61,30 @@ public Enumeration getAllDrivers(ClassLoaderLeakPreventor preventor) { } return result.elements(); } + + private void deregisterDriver(ClassLoaderLeakPreventor preventor, final Driver driver) throws Exception { + synchronized (DriverManager.class) { + if (driver == null) { + return; + } + try { + List registeredDrivers = preventor.getStaticFieldValue(DriverManager.class, "registeredDrivers"); + Class innerClass = Class.forName("java.sql.DriverInfo"); + Constructor ctor = innerClass.getDeclaredConstructor(Driver.class, DriverAction.class); + ctor.setAccessible(true); + Object innerInstance = ctor.newInstance(driver, null); + Object di = registeredDrivers.get(registeredDrivers.indexOf(innerInstance)); + Method actionMethod = innerClass.getDeclaredMethod("action", new Class[0]); + actionMethod.setAccessible(true); + DriverAction da = (DriverAction) actionMethod.invoke(di); + if (da != null) { + da.deregister(); + } + registeredDrivers.remove(innerInstance); + } catch (Exception e) { + preventor.error("deregisterDriver error"); + throw e; + } + } + } } From 4dcd5c067410ac9584c53ceaa5b139be860b981b Mon Sep 17 00:00:00 2001 From: songqingqing Date: Wed, 2 May 2018 08:53:04 +0800 Subject: [PATCH 05/16] bugfix:Do the work as DriverManager.deregisterDriver by reflection --- .../leak/prevention/cleanup/DriverManagerCleanUp.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java index e698f6f0..a525cb27 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java +++ b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java @@ -5,7 +5,6 @@ import java.sql.Driver; import java.sql.DriverAction; import java.sql.DriverManager; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; @@ -37,7 +36,7 @@ public void cleanUp(ClassLoaderLeakPreventor preventor) { } /** - * Add getAllDrivers method. DriverManager.getDrivers() only return the drivers + * DriverManager.getDrivers() only return the drivers * which be load by caller(DriverManagerCleanUp.class). For many scenarios the * caller is not the same classloader which load the jdbc drivers. * @param preventor @@ -62,6 +61,9 @@ public Enumeration getAllDrivers(ClassLoaderLeakPreventor preventor) { return result.elements(); } + /** + *Do the work as DriverManager.deregisterDriver,but this method don't check the Security of the caller's Classloader + */ private void deregisterDriver(ClassLoaderLeakPreventor preventor, final Driver driver) throws Exception { synchronized (DriverManager.class) { if (driver == null) { From 06555f461f085e7d6bd34463542e1327f9214ced Mon Sep 17 00:00:00 2001 From: songqingqing Date: Wed, 2 May 2018 08:54:39 +0800 Subject: [PATCH 06/16] bugfix:Do the work as DriverManager.deregisterDriver by reflection --- .../leak/prevention/cleanup/DriverManagerCleanUp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java index a525cb27..4db96b77 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java +++ b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java @@ -46,7 +46,7 @@ public void cleanUp(ClassLoaderLeakPreventor preventor) { public Enumeration getAllDrivers(ClassLoaderLeakPreventor preventor) { Vector result = new java.util.Vector(); try { - ArrayList driverinfos = preventor.getStaticFieldValue(DriverManager.class, "registeredDrivers"); + List driverinfos = preventor.getStaticFieldValue(DriverManager.class, "registeredDrivers"); for (Object driverinfo : driverinfos) { Driver driver = (Driver) preventor.getFieldValue(driverinfo, "driver"); if (driver == null) From fdfad5817b57528eb52c813f7aaeae4bf58c15e2 Mon Sep 17 00:00:00 2001 From: songqingqing Date: Wed, 2 May 2018 08:55:46 +0800 Subject: [PATCH 07/16] refactor import --- .../leak/prevention/cleanup/DriverManagerCleanUp.java | 1 - 1 file changed, 1 deletion(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java index 4db96b77..39121ba4 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java +++ b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java @@ -5,7 +5,6 @@ import java.sql.Driver; import java.sql.DriverAction; import java.sql.DriverManager; -import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Vector; From f5400e70981c5d92268aa024f1f7f0a37fd9973a Mon Sep 17 00:00:00 2001 From: songqingqing Date: Wed, 2 May 2018 15:22:19 +0800 Subject: [PATCH 08/16] Code changed to compatibile JDK7 --- .../cleanup/DriverManagerCleanUp.java | 106 +++++++++++------- 1 file changed, 64 insertions(+), 42 deletions(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java index 39121ba4..e149d1ef 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java +++ b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java @@ -3,7 +3,6 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.sql.Driver; -import java.sql.DriverAction; import java.sql.DriverManager; import java.util.Enumeration; import java.util.List; @@ -14,54 +13,57 @@ /** * Deregister JDBC drivers loaded by classloader + * * @author Mattias Jiderhamn * @author SONGQQ 2018-4-19 */ public class DriverManagerCleanUp implements ClassLoaderPreMortemCleanUp { @Override public void cleanUp(ClassLoaderLeakPreventor preventor) { - final Enumeration allDrivers = getAllDrivers(preventor); - while (allDrivers.hasMoreElements()) { - final Driver driver = allDrivers.nextElement(); - if (preventor.isLoadedInClassLoader(driver)) { - try { - preventor.warn("JDBC driver loaded by protected ClassLoader deregistered: " + driver.getClass()); - deregisterDriver(preventor, driver); - } catch (Exception e) { - preventor.error(e); - } - } - } + final Enumeration allDrivers = getAllDrivers(preventor); + while (allDrivers.hasMoreElements()) { + final Driver driver = allDrivers.nextElement(); + if (preventor.isLoadedInClassLoader(driver)) { + try { + preventor.warn("JDBC driver loaded by protected ClassLoader deregistered: " + driver.getClass()); + deregisterDriver(preventor, driver); + } catch (Exception e) { + preventor.error(e); + } + } + } } /** - * DriverManager.getDrivers() only return the drivers - * which be load by caller(DriverManagerCleanUp.class). For many scenarios the - * caller is not the same classloader which load the jdbc drivers. + * DriverManager.getDrivers() only return the drivers which be load by + * caller(DriverManagerCleanUp.class). For many scenarios the caller is not the + * same classloader which load the jdbc drivers. + * * @param preventor * @return All drivers in DriverManager's registeredDrivers field,or * DriverManager.getDrivers() if exception occurred */ public Enumeration getAllDrivers(ClassLoaderLeakPreventor preventor) { - Vector result = new java.util.Vector(); - try { - List driverinfos = preventor.getStaticFieldValue(DriverManager.class, "registeredDrivers"); - for (Object driverinfo : driverinfos) { - Driver driver = (Driver) preventor.getFieldValue(driverinfo, "driver"); - if (driver == null) - throw new NullPointerException(); - else - result.addElement(driver); - } - } catch (Exception e) { - preventor.warn("get All registeredDrivers Exception"); - return DriverManager.getDrivers(); - } - return result.elements(); + Vector result = new java.util.Vector(); + try { + List driverinfos = preventor.getStaticFieldValue(DriverManager.class, "registeredDrivers"); + for (Object driverinfo : driverinfos) { + Driver driver = (Driver) preventor.getFieldValue(driverinfo, "driver"); + if (driver == null) + throw new NullPointerException(); + else + result.addElement(driver); + } + } catch (Exception e) { + preventor.warn("get All registeredDrivers Exception"); + return DriverManager.getDrivers(); + } + return result.elements(); } /** - *Do the work as DriverManager.deregisterDriver,but this method don't check the Security of the caller's Classloader + * Do the work as DriverManager.deregisterDriver,but this method don't check the + * Security of the caller's Classloader.If Exception occur,it's invoke the DriverManager.deregisterDriver(driver) ; */ private void deregisterDriver(ClassLoaderLeakPreventor preventor, final Driver driver) throws Exception { synchronized (DriverManager.class) { @@ -71,19 +73,39 @@ private void deregisterDriver(ClassLoaderLeakPreventor preventor, final Driver d try { List registeredDrivers = preventor.getStaticFieldValue(DriverManager.class, "registeredDrivers"); Class innerClass = Class.forName("java.sql.DriverInfo"); - Constructor ctor = innerClass.getDeclaredConstructor(Driver.class, DriverAction.class); - ctor.setAccessible(true); - Object innerInstance = ctor.newInstance(driver, null); - Object di = registeredDrivers.get(registeredDrivers.indexOf(innerInstance)); - Method actionMethod = innerClass.getDeclaredMethod("action", new Class[0]); - actionMethod.setAccessible(true); - DriverAction da = (DriverAction) actionMethod.invoke(di); - if (da != null) { - da.deregister(); + Method actionMethod = null; + Object innerInstance = null; + //DriverInfo is Changed in JDK8. So the Code must be backward compatibility. + try { + actionMethod = innerClass.getDeclaredMethod("action", new Class[0]); + } catch (NoSuchMethodException e) { + preventor.info("DriverInfo NoSuchMethod:action,Means it's running before JDK8"); } + Constructor ctor = null; + if (actionMethod != null) { + ctor = innerClass.getDeclaredConstructor(Driver.class, actionMethod.getReturnType()); + ctor.setAccessible(true); + innerInstance = ctor.newInstance(driver, null); + Object di = registeredDrivers.get(registeredDrivers.indexOf(innerInstance)); + + actionMethod.setAccessible(true); + Object da = actionMethod.invoke(di); + if (da != null) { + Method deregisterMethod = da.getClass().getDeclaredMethod("deregister", new Class[0]); + if (deregisterMethod != null) + deregisterMethod.invoke(da); + } + + } else { + ctor = innerClass.getDeclaredConstructor(Driver.class); + ctor.setAccessible(true); + innerInstance = ctor.newInstance(driver); + } + registeredDrivers.remove(innerInstance); } catch (Exception e) { - preventor.error("deregisterDriver error"); + preventor.error("reflection to deregisterDriver error,invoke the orgin DriverManager.deregisterDriver()"); + DriverManager.deregisterDriver(driver); throw e; } } From 3dd4b4b57623becbfe1c5d234adf259bc0a25b63 Mon Sep 17 00:00:00 2001 From: songqingqing Date: Wed, 2 May 2018 15:23:26 +0800 Subject: [PATCH 09/16] Code changed to compatibile JDK7 --- .../leak/prevention/cleanup/DriverManagerCleanUp.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java index e149d1ef..828c1af4 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java +++ b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java @@ -38,8 +38,6 @@ public void cleanUp(ClassLoaderLeakPreventor preventor) { * DriverManager.getDrivers() only return the drivers which be load by * caller(DriverManagerCleanUp.class). For many scenarios the caller is not the * same classloader which load the jdbc drivers. - * - * @param preventor * @return All drivers in DriverManager's registeredDrivers field,or * DriverManager.getDrivers() if exception occurred */ From 516dfbf6ab0924ce838cf837d9eafe9c36df3fcc Mon Sep 17 00:00:00 2001 From: Chiranjivee Thakur Date: Tue, 22 May 2018 22:57:51 +0530 Subject: [PATCH 10/16] Fix Init sun.misc.GC for Java 9 Summary: In java 9, sun.misc.GC is moved to sun.rmi.transport.GC , trying again if sun.misc.GC is not found else throwing ClassNotFoundException. --- .../leak/prevention/preinit/SunGCInitiator.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/preinit/SunGCInitiator.java b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/preinit/SunGCInitiator.java index c280fe52..0f8f767f 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/preinit/SunGCInitiator.java +++ b/classloader-leak-prevention/classloader-leak-prevention-core/src/main/java/se/jiderhamn/classloader/leak/prevention/preinit/SunGCInitiator.java @@ -22,8 +22,9 @@ public class SunGCInitiator implements PreClassLoaderInitiator { @Override public void doOutsideClassLoader(ClassLoaderLeakPreventor preventor) { try { - Class gcClass = Class.forName("sun.misc.GC"); + Class gcClass = this.getGCClass(); final Method requestLatency = gcClass.getDeclaredMethod("requestLatency", long.class); + requestLatency.setAccessible(true); requestLatency.invoke(null, Long.valueOf(Long.MAX_VALUE - 1)); } catch (ClassNotFoundException cnfex) { @@ -39,6 +40,14 @@ public void doOutsideClassLoader(ClassLoaderLeakPreventor preventor) { catch (InvocationTargetException itex) { preventor.error(itex); } - + } + + private Class getGCClass() throws ClassNotFoundException { + try { + return Class.forName("sun.misc.GC"); + } catch (ClassNotFoundException cnfex) { + // Try Jre 9 classpath + return Class.forName("sun.rmi.transport.GC"); + } } } \ No newline at end of file From 64e2cacbc6cce084d31c4987b4958b52a090663c Mon Sep 17 00:00:00 2001 From: Mattias Jiderhamn Date: Tue, 29 May 2018 12:29:34 +0200 Subject: [PATCH 11/16] 2.6.1 released, updating README.md Conflicts: README.md classloader-leak-prevention/classloader-leak-prevention-core/README.md --- README.md | 4 ++-- .../classloader-leak-prevention-core/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0b13cb82..be953a3d 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ dependency in your `.war`: se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-servlet3 - 2.5.0 + 2.6.1 ``` @@ -31,7 +31,7 @@ Maven dependency (notice the difference in `artifactId`): se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-servlet - 2.5.0 + 2.6.1 ``` diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/README.md b/classloader-leak-prevention/classloader-leak-prevention-core/README.md index 470f8b9d..3869e77c 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/README.md +++ b/classloader-leak-prevention/classloader-leak-prevention-core/README.md @@ -58,6 +58,6 @@ The module is available in Maven as se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-core - 2.5.0 + 2.6.1 ``` \ No newline at end of file From 6a13eff03fc8963618945cbaaacc9bd6f0f97294 Mon Sep 17 00:00:00 2001 From: Mattias Jiderhamn Date: Tue, 29 May 2018 12:22:00 +0200 Subject: [PATCH 12/16] [maven-release-plugin] prepare for next development iteration Conflicts: classloader-leak-prevention/classloader-leak-prevention-core/pom.xml classloader-leak-prevention/classloader-leak-prevention-servlet/pom.xml classloader-leak-prevention/classloader-leak-prevention-servlet3/pom.xml classloader-leak-prevention/pom.xml --- .../classloader-leak-prevention-core/pom.xml | 4 ++++ .../classloader-leak-prevention-servlet/pom.xml | 4 ++++ .../classloader-leak-prevention-servlet3/pom.xml | 4 ++++ classloader-leak-prevention/pom.xml | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml b/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml index 5a80bb79..643b445b 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml +++ b/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml @@ -3,7 +3,11 @@ se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-parent +<<<<<<< master 2.5.1-SNAPSHOT +======= + 2.6.2-SNAPSHOT +>>>>>>> 5cf9a75 [maven-release-plugin] prepare for next development iteration classloader-leak-prevention-core diff --git a/classloader-leak-prevention/classloader-leak-prevention-servlet/pom.xml b/classloader-leak-prevention/classloader-leak-prevention-servlet/pom.xml index 504f4f4d..a26c1706 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-servlet/pom.xml +++ b/classloader-leak-prevention/classloader-leak-prevention-servlet/pom.xml @@ -4,7 +4,11 @@ se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-parent +<<<<<<< master 2.5.1-SNAPSHOT +======= + 2.6.2-SNAPSHOT +>>>>>>> 5cf9a75 [maven-release-plugin] prepare for next development iteration classloader-leak-prevention-servlet jar diff --git a/classloader-leak-prevention/classloader-leak-prevention-servlet3/pom.xml b/classloader-leak-prevention/classloader-leak-prevention-servlet3/pom.xml index 73a26cab..c4a479a2 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-servlet3/pom.xml +++ b/classloader-leak-prevention/classloader-leak-prevention-servlet3/pom.xml @@ -4,7 +4,11 @@ se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-parent +<<<<<<< master 2.5.1-SNAPSHOT +======= + 2.6.2-SNAPSHOT +>>>>>>> 5cf9a75 [maven-release-plugin] prepare for next development iteration classloader-leak-prevention-servlet3 jar diff --git a/classloader-leak-prevention/pom.xml b/classloader-leak-prevention/pom.xml index 93ecede7..be6850e4 100644 --- a/classloader-leak-prevention/pom.xml +++ b/classloader-leak-prevention/pom.xml @@ -3,7 +3,11 @@ se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-parent +<<<<<<< master 2.5.1-SNAPSHOT +======= + 2.6.2-SNAPSHOT +>>>>>>> 5cf9a75 [maven-release-plugin] prepare for next development iteration pom ClassLoader Leak Prevention library parent Library that prevents ClassLoader leaks / java.lang.OutOfMemoryError: PermGen space From 60fbbac034afb057ad1a4f8ed00270184ca5a239 Mon Sep 17 00:00:00 2001 From: songqingqing Date: Thu, 31 May 2018 09:58:38 +0800 Subject: [PATCH 13/16] Revert "[maven-release-plugin] prepare for next development iteration" This reverts commit 6a13eff03fc8963618945cbaaacc9bd6f0f97294. --- .../classloader-leak-prevention-core/pom.xml | 4 ---- .../classloader-leak-prevention-servlet/pom.xml | 4 ---- .../classloader-leak-prevention-servlet3/pom.xml | 4 ---- classloader-leak-prevention/pom.xml | 4 ---- 4 files changed, 16 deletions(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml b/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml index 643b445b..5a80bb79 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml +++ b/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml @@ -3,11 +3,7 @@ se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-parent -<<<<<<< master 2.5.1-SNAPSHOT -======= - 2.6.2-SNAPSHOT ->>>>>>> 5cf9a75 [maven-release-plugin] prepare for next development iteration classloader-leak-prevention-core diff --git a/classloader-leak-prevention/classloader-leak-prevention-servlet/pom.xml b/classloader-leak-prevention/classloader-leak-prevention-servlet/pom.xml index a26c1706..504f4f4d 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-servlet/pom.xml +++ b/classloader-leak-prevention/classloader-leak-prevention-servlet/pom.xml @@ -4,11 +4,7 @@ se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-parent -<<<<<<< master 2.5.1-SNAPSHOT -======= - 2.6.2-SNAPSHOT ->>>>>>> 5cf9a75 [maven-release-plugin] prepare for next development iteration classloader-leak-prevention-servlet jar diff --git a/classloader-leak-prevention/classloader-leak-prevention-servlet3/pom.xml b/classloader-leak-prevention/classloader-leak-prevention-servlet3/pom.xml index c4a479a2..73a26cab 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-servlet3/pom.xml +++ b/classloader-leak-prevention/classloader-leak-prevention-servlet3/pom.xml @@ -4,11 +4,7 @@ se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-parent -<<<<<<< master 2.5.1-SNAPSHOT -======= - 2.6.2-SNAPSHOT ->>>>>>> 5cf9a75 [maven-release-plugin] prepare for next development iteration classloader-leak-prevention-servlet3 jar diff --git a/classloader-leak-prevention/pom.xml b/classloader-leak-prevention/pom.xml index be6850e4..93ecede7 100644 --- a/classloader-leak-prevention/pom.xml +++ b/classloader-leak-prevention/pom.xml @@ -3,11 +3,7 @@ se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-parent -<<<<<<< master 2.5.1-SNAPSHOT -======= - 2.6.2-SNAPSHOT ->>>>>>> 5cf9a75 [maven-release-plugin] prepare for next development iteration pom ClassLoader Leak Prevention library parent Library that prevents ClassLoader leaks / java.lang.OutOfMemoryError: PermGen space From c97209ccf85af4f9544af73f9a5b59d7688573b9 Mon Sep 17 00:00:00 2001 From: Mattias Jiderhamn Date: Tue, 29 May 2018 12:22:00 +0200 Subject: [PATCH 14/16] [maven-release-plugin] prepare for next development iteration Conflicts: classloader-leak-prevention/classloader-leak-prevention-core/pom.xml classloader-leak-prevention/classloader-leak-prevention-servlet/pom.xml classloader-leak-prevention/classloader-leak-prevention-servlet3/pom.xml classloader-leak-prevention/pom.xml --- .../classloader-leak-prevention-core/pom.xml | 16 +++++++++++++++- .../classloader-leak-prevention-servlet/pom.xml | 2 +- .../classloader-leak-prevention-servlet3/pom.xml | 2 +- classloader-leak-prevention/pom.xml | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml b/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml index 5a80bb79..f06778b5 100644 --- a/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml +++ b/classloader-leak-prevention/classloader-leak-prevention-core/pom.xml @@ -3,7 +3,7 @@ se.jiderhamn.classloader-leak-prevention classloader-leak-prevention-parent - 2.5.1-SNAPSHOT + 2.6.2-SNAPSHOT classloader-leak-prevention-core @@ -110,6 +110,20 @@ 9.4-1201-jdbc41 test + + + org.eclipse.persistence + org.eclipse.persistence.moxy + 2.7.0 + test + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.2 + test +