Bug #71432 Key store files not closed when making SSL connection
Submitted: 20 Jan 2014 17:22 Modified: 10 Mar 2014 20:00
Reporter: David Huebel Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version: OS:Any
Assigned to: Alexander Soklakov CPU Architecture:Any

[20 Jan 2014 17:22] David Huebel
Description:
We are debugging an intermittent issue resulting in our trust store file being open hundreds of times.  In ExportControlled.java, I found the following two places in which an input stream is opened and not subsequently closed: 

    clientKeyStore.load(ksURL.openStream(), password); // line 160 in 5.1.28 

    trustKeyStore.load(ksURL.openStream(), password); // line 204 in 5.1.28 

The Javadoc for KeyStore (http://docs.oracle.com/javase/6/docs/api/java/security/KeyStore.html) does not specify whether KeyStore closes the stream after loading it (and it is possible that some implementations do,) but the Javadoc does provide sample code in which the caller explicitly closes the stream after calling load:

    java.io.FileInputStream fis = null;
    try {
        fis = new java.io.FileInputStream("keyStoreName");
        ks.load(fis, password);
    } finally {
        if (fis != null) {
            fis.close();
        }
    }

Depending on performance conditions, we sporadically encounter situations in which the trust store file is open hundreds of times, contributing to "too many open files" errors.  This is consistent with the file being left open until the stream is finalized.

How to repeat:
We see the problem while running a section of code that repeatedly opens a connection to the database, runs one query, and closes the connection.  We do not know the exact conditions required to cause the number of open files to balloon into the hundreds, but in normal usage, the number of times the trust store is opened seems to be larger than expected.

Suggested fix:
Replace line 204:

                                        trustKeyStore.load(ksURL.openStream(), password);

with:

                                        InputStream is = null;
                                        try {
                                            is = ksURL.openStream();
                                            trustKeyStore.load(is, password);
                                        } finally {
                                            if (is != null) {
                                                is.close();
                                            }
                                        }

And similarly for line 160.  These two changes appear to fix our problem, but since the issue is intermittent, we are not one hundred percent certain.
[20 Jan 2014 17:24] David Huebel
ExportControlled.java with changes to explicitly close streams

Attachment: ExportControlled.java (application/octet-stream, text), 11.29 KiB.

[20 Jan 2014 17:25] David Huebel
Patched version of ExportControlled.java attached
[21 Jan 2014 7:05] Alexander Soklakov
Hi David,

Thank you, it's important. Verified by code review.
[10 Mar 2014 20:00] Daniel So
Added the following entry to the Connector/J 5.1.30 changelog:

"There were sporadic cases of the key store file being open hundreds of times and causing some "Too many files open" errors. This fix makes sure that in com.mysql.jdbc.ExportControlled and in MysqlIO.sendFileToServer(), the input stream for the key store file is explicitly closed after use."