Bug #45577 Undeploy application still hold lock to mysql-connector-java.jar
Submitted: 18 Jun 7:48 Modified: 14 Aug 23:48
Reporter: Vlad Skarzhevskyy
Status: Verified
Category:Connector/J Severity:S3 (Non-critical)
Version:5.1.7 OS:Microsoft Windows (Win XP sp3)
Assigned to: Mark Matthews Target Version:
Triage: D4 (Minor)

[18 Jun 7:48] Vlad Skarzhevskyy
Description:
After upgrade from 5.1.5 to 5.1.6 web application fails to undeploy properly.
The mysql jdbc jar file still locked.

Also tested with mysql-connector-java 5.1.7 the same problem.
Java Profiler shows that some com.mysql.jdbc classes are still used. and not garbage
collected.

We do call java.sql.DriverManager.deregisterDriver(..) in
ServletContextListener.contextDestroyed() so undeploy worked fine with older versions.

-- 
The most annoying problem (May be clue) is even if application is using oracle jdbc the
mysql-connector jar is still locked after web application is undeplyed.
(We do have this two drivers included in war)

---
Environment: Win XP or Server 2003, SUN Java 1.6 or JRockit_160_05, Apache Tomcat/6.0.20

How to repeat:
Web application mysql-connector-java.jar included in WEB-INF\lib
Start web application in Tomcat 6.  
     it should connect to db using any JDBC driver.
Undeploy application
The only file remaining from the application is mysql-connector-java.jar

----
I can help to create small testing web application or whatever required.
[18 Jun 11:47] Tonci Grgin
Hi Vlad and thanks for your report.

> Java Profiler shows that some com.mysql.jdbc classes are still used. and not garbage
collected.

Tuning GC is an art in itself... Did you tried more aggressive settings or parallel GC?

>How to repeat: Web application mysql-connector-java.jar included in WEB-INF\lib

What is this "WEB-INF\lib" you're talking about? Did you tried creating stand-alone test
case (no Apache and such)? Have you tried setting "holdResultsOpenOverStatementClose" to
false?

Please attach small but complete test case demonstrating unwanted behavior.
[18 Jun 15:10] Vlad Skarzhevskyy
Empty Web application sources maven build

Attachment: sql-web-app-sources.zip (application/zip, text), 2.51 KiB.

[18 Jun 15:14] Tonci Grgin
Vlad, I am sorry but I still don't see a valid test case in your attachment... Am I
missing something here?
[18 Jun 15:17] Vlad Skarzhevskyy
Created and Empty web application to show the bug!

Nothing in the war but mysql jar!!!!! Not even opening connection to Any DB!

Maven2 build file:
http://pyx4j.com/downloads/mysql/sql-web-app-sources.zip

Resulting war
http://pyx4j.com/downloads/mysql/sql-web-app.war
[18 Jun 15:25] Vlad Skarzhevskyy
Hi Tonci
  The valid test is deploy war on Tomcat and then undeply it!  All on Windows! On Linux
it may work properly since it has different file locking....

 Also regarding your previous comments:
1)  WEB-INF\lib   is a special directory in war archive where all there required for web
application jar are going.  

2) The GC configuration may have nothing to do with this.
 In profiler I see that classes are references by root class loader and not the instances
of the classes.  Will add the picture in next upload.
[18 Jun 16:03] Vlad Skarzhevskyy
I did some profiling, for this DriverManager.deregisterDriver has been added to
application: http://pyx4j.com/downloads/mysql/sql-web-app-all-4-profiler.zip

I can't see any mysql instance or classes been retained after the app is stopped and
undeployed.

Definitely you have some unclosed resources that are loaded from jar...
I would try to find them if I can.

But honestly do you need this exercise? Can you find from the changes in source
from version 5.1.5 to 5.1.6  what has been changed to live lock on the jar

If you have url.url.openConnection()  from  the jar then this will lock the jar!
Call it JVM bug but there is a work around this:

-----
InputStream input = null;
try {
    URLConnection connection = url.openConnection();
    if (connection instanceof JarURLConnection) {
        ((JarURLConnection) connection).setUseCaches(false);
    }
    input = connection.getInputStream();
    .. DO your job 
} finally {
    if(input != null) {
        try {
            input.close();
        } catch (Throwable ignore) {
        }
    }
} 
-----
[20 Jun 11:40] Tonci Grgin
Jess will follow up on this.
[20 Jun 11:43] Tonci Grgin
Vlad, we think this could be related to (see 5.1.6 change log):
    - Fixed issue where META-INF in the binary .jar file wasn't packed correctly,
      leading to failure of the JDBC-4.0 SPI mechanism.
but Jess will know more.
[22 Jun 6:03] Jess Balint
Verified as described. Workaround is to use "antiResourceLocking=true" as a Tomcat Context
attribute.
[25 Sep 18:14] Ed S
I have the same problem on v5.1.9.  I understand the workaround is to use
"antiResourceLocking=true" in the tomcat context.xml file.  However, I will be deploying
to a web hosting center of which I do not have access to make system configuration
changes.  Also, some of the documentation I've been reading says to put the jdbc driver
jar file in the tomcat putting the jdbc driver in common/lib for tomcat.  This doesn't
work for hosting centers where you do not have that level of access.
Is there another workaround for this?
Note: I have already tried the ContextListener contextDestroyed method to
DriverManger.deregisterDriver, as well as another tip I found about a timer needing to be
cancelled.  Please help