Bug #62518 | Connector/J - Named Pipe connection cannot be closed | ||
---|---|---|---|
Submitted: | 23 Sep 2011 17:10 | Modified: | 17 Nov 2011 14:37 |
Reporter: | Lucas Still | Email Updates: | |
Status: | Won't fix | Impact on me: | |
Category: | Connector / J | Severity: | S2 (Serious) |
Version: | Community Server 5.5.15 | OS: | Windows (7) |
Assigned to: | Bogdan Degtyariov | CPU Architecture: | Any |
Tags: | Connector/J, Named-Pipe |
[23 Sep 2011 17:10]
Lucas Still
[23 Sep 2011 19:29]
Lucas Still
Accidental severity selection corrected.
[9 Nov 2011 8:48]
Bogdan Degtyariov
Verified using 5.1.18. What is interesting - the database queries and results work as normal, it is just connection.close() failing.
[9 Nov 2011 14:55]
Lucas Still
Indeed. It isn't a game breaker, but I'm not positive about the compounding ramifications of failed closings.
[10 Nov 2011 2:42]
Bogdan Degtyariov
Lucas, you are absolutely right. This must be fixed.
[10 Nov 2011 2:48]
Mark Matthews
I don't think this is a driver bug. When one calls Connection.close(), it ends up calling Socket.close() on the socket in question. In this case, it's com.mysql.jdbc.NamedPipeSocket. This does the following: public synchronized void close() throws IOException { this.namedPipeFile.close(); this.isClosed = true; } If that's not enough to get the other end of the connection to "die", then there's not really much of anything that can be done from the driver side of things. It's either a JVM bug, or it's a Windows bug.
[10 Nov 2011 2:53]
Lucas Still
Is it that, or is the driver not properly keeping the socket "alive" so that it may be closed later? The only reason I ask this is because of the wording in the error message: "MESSAGE: Socket is not connected". This would lead me to believe that the socket was already "killed" before .close() was even called.
[10 Nov 2011 14:21]
Mark Matthews
This message is due to us trying to do Socket.shutdownInput(), which doesn't actually work on our socket wrapper around RandomAccessFile (which is why it's a warning).
[14 Nov 2011 6:14]
Bogdan Degtyariov
Mark, I tried debugging Connector/J and found one interesting thing, which might be helpful: The method you named (com.mysql.jdbc.NamedPipeSocket.close()) is called after the exception is thrown. Here is the stack tracke for the exception: java.net.SocketException: Socket is not connected at java.net.Socket.shutdownInput(Socket.java:1346) at com.mysql.jdbc.MysqlIO.quit(MysqlIO.java:1696) at com.mysql.jdbc.ConnectionImpl.realClose(ConnectionImpl.java:4371) at com.mysql.jdbc.ConnectionImpl.close(ConnectionImpl.java:1556) at bug62518.main(bug62518.java:24) Here is the stack trace for the close() call, which actually closes the pipe: Thread [main] (Suspended (breakpoint at line 64 in NamedPipeSocketFactory$NamedPipeSocket)) NamedPipeSocketFactory$NamedPipeSocket.close()(NamedPipeSocketFactory.java line: 64) MysqlIO.forceClose()(MysqlIO.java: 542) MysqlIO.quit()(MysqlIO.java: 1710) <-------------- pipe closure ConnectionImpl.realClose()(ConnectionImpl.java:4371) ConnectionImpl.close()(ConnectionImpl.java:1556) bug62518.main(String[])(bug62518.java:24) Maybe this.mysqlConnection.shutdownInput(); (MysqlIO.java:1696) should not be called at all for pipe connections and let forceClose(); (MysqlIO.java: 1710) finish the job.
[14 Nov 2011 20:06]
Mark Matthews
It's not an exception, it's a log message: catch (IOException ioEx) { this.connection.getLog().logWarn("Caught while disconnecting...", ioEx); } This doesn't prevent the close() of the underlying socket, and thus random access file in the named pipe's case from happening as far as I can see.
[15 Nov 2011 3:48]
Bogdan Degtyariov
Thanks Mark, that makes sense. Have to try with C API client and see if a similar problem occurs.
[17 Nov 2011 6:27]
Bogdan Degtyariov
MySQL C API client processed the pipe connect/disconnect quite well. Indeed, mysql_close() function does not return any result or error. Uploading the C test case below.
[17 Nov 2011 6:28]
Bogdan Degtyariov
C test case
Attachment: bug62518.c (text/plain), 1.12 KiB.
[17 Nov 2011 11:08]
Bogdan Degtyariov
Another test using C/NET showed no problems as well. private void button8_Click(object sender, EventArgs e) { using (MySqlConnection conn = new MySqlConnection( "server=.;protocol=pipe;database=test;User Id=*****;password=******")) { conn.Open(); MessageBox.Show("Connection opened"); // just to see that something is actually going on String SQL = "SHOW VARIABLES LIKE '%timeout'"; using (MySqlCommand cmd = new MySqlCommand(SQL, conn)) { cmd.CommandType = System.Data.CommandType.Text; MySqlDataReader dr = cmd.ExecuteReader(); MessageBox.Show("Behold!!!!"); String cnames = ""; while (dr.Read()) { cnames += dr[0] + " : " + dr[1] + "\r\n"; } MessageBox.Show("Results: \r\n\r\n" + cnames); } conn.Close(); MessageBox.Show("Closed!"); } }
[17 Nov 2011 14:00]
Mark Matthews
We can verify that close() is called on the underlying file descriptor, so we'll have to leave this chalked up to a JVM bug, unfortunately.
[17 Nov 2011 14:37]
Tonci Grgin
Bogdan, thanks for your efforts. Setting to "Won't Fix" as per Mark's comment.
[31 May 2013 11:43]
Vladislav Vaintroub
Why not you just overwrite shutdownSocket() in the custom socket class, so it does nothing?