-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DriverManagerCleanUp can't really work for many scenarios #80
base: master
Are you sure you want to change the base?
Conversation
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
Could you please adhere to the coding standards of the project, such as indentation with 2 spaces, camel humping etc? |
* Deregister JDBC drivers loaded by classloader | ||
* | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why these empty JavaDoc lines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry I use the diffenrent Java code style template ,i shoud follow your project coding standards
preventor.warn("get All registeredDrivers Exception "); | ||
preventor.error(e); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we default to DriverManager.getDrivers()
in case reflection fails?
catch (Exception e) { | ||
preventor.warn("get All registeredDrivers Exception "); | ||
preventor.error(e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should decide whether this makes up a warning or an error - not both
|
||
} | ||
return (result.elements()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the extra parethesis
@Override | ||
public void cleanUp(ClassLoaderLeakPreventor preventor) { | ||
final List<Driver> driversToDeregister = new ArrayList<Driver>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this list even needed now that we know we won't cause ConcurrentModificationException (depending on the reflectino fall below, by all means), or can't we deregister in the first loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes,driversToDeregister is no need any more.
while (allDrivers.hasMoreElements()) { | ||
final Driver driver = allDrivers.nextElement(); | ||
if (preventor.isLoadedInClassLoader(driver)) // Should be true for all returned by DriverManager.getDrivers() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the comment still relevant?
* @param preventor | ||
* @return | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please clarify the JavaDoc
* @return | ||
*/ | ||
public java.util.Enumeration<Driver> getAllDrivers(ClassLoaderLeakPreventor preventor) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Enumeration
rather than Collection
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DriverManager.getDrivers() return type is Enumeration
*/ | ||
public java.util.Enumeration<Driver> getAllDrivers(ClassLoaderLeakPreventor preventor) { | ||
java.util.Vector<Driver> result = new java.util.Vector<Driver>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Vector
rather than ArrayList
? Synchronization cannot possibly be needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because method DriverManager.getDrivers() use Vector,So i follow the usage
java.util.Vector<Driver> result = new java.util.Vector<Driver>(); | ||
try { | ||
CopyOnWriteArrayList<?> driverinfos = preventor.getStaticFieldValue(DriverManager.class, "registeredDrivers"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest using List
(or even Collection
) as the variable type, and by all means keep CopyOnWriteArrayList
as a comment. That way this class still works even if the internals of DriverManager
is updated to use something other than CopyOnWriteArrayList
What is the scenario we're trying to solve here? The leak prevention library being part of a framework/application server, while the JDBC driver is dynamically loaded in an application instance (.war file)? |
Yes I have a app server. which have two level classloader. the server classloader load classloader-leak-prevention.jar .The server main-thread execute: runPreClassLoaderInitiators -> start war classloader (war-classloader load jdbc drivers / .war etc)->runCleanUps I modify the code, please see the code again. |
modify code style; return DriverManager.getDrivers() if Exception occurred
* @param preventor | ||
* @return All drivers in DriverManager's registeredDrivers field,or | ||
* DriverManager.getDrivers() if exception occurred | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please clean up the JavaDoc a bit. (For example, you don't need to document method X with "Add X method". Either add documentation or remove @param
)
} | ||
} catch (Exception e) { | ||
preventor.warn("get All registeredDrivers Exception"); | ||
return DriverManager.getDrivers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code now assumes the returned Enumeration does not cause ConcurrentModificationException
if driver is removed while looping. Is that guaranteed by the API contract, or should we make of copy to ensure the library does not start failing in case the DriverManager
internals happens to be changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's no reason the jdk developer to changed the default manner of getDrivers. they are already considered avoid ConcurrentModificationException in current code.
} | ||
return result.elements(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this inside try
(unless used for copying, see below)
* DriverManager.getDrivers() if exception occurred | ||
*/ | ||
public Enumeration<Driver> getAllDrivers(ClassLoaderLeakPreventor preventor) { | ||
Vector<Driver> result = new java.util.Vector<Driver>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this inside try
(unless used for copying, see below)
|
Good catch @OlegYch ! |
@OlegYch thanks your advices. |
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.
Conflicts: README.md classloader-leak-prevention/classloader-leak-prevention-core/README.md
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
This reverts commit 6a13eff.
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
...ore/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java
Outdated
Show resolved
Hide resolved
...ore/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java
Outdated
Show resolved
Hide resolved
...ore/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java
Outdated
Show resolved
Hide resolved
...ore/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java
Outdated
Show resolved
Hide resolved
...ore/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java
Outdated
Show resolved
Hide resolved
...ore/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java
Outdated
Show resolved
Hide resolved
...ore/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java
Outdated
Show resolved
Hide resolved
...ore/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java
Outdated
Show resolved
Hide resolved
...ore/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java
Outdated
Show resolved
Hide resolved
...ore/src/main/java/se/jiderhamn/classloader/leak/prevention/cleanup/DriverManagerCleanUp.java
Outdated
Show resolved
Hide resolved
I accept your suggestion,please review again. |
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. So ,DriverManager.getDrivers() will return empty driver list,and DriverManagerCleanUp do nothing.
I think it need get registeredDrivers by reflection.