locked
JDBC driver 3.0 'hanging' on authentication step RRS feed

  • Question

  • Our application sometimes has problems getting new connections. The default SQL JDBC connection timeout of 15 seconds passes without any reaction, and after 5 more seconds, our threadmonitor thread tries an interrupt(), but after no reaction on that,  has to stop() the thread.

    Client Microsoft Windows 2008r2 x64

    URL jdbc:sqlserver://sqlserver:1433

    Driver "Microsoft SQL Server JDBC Driver 3.0" VERSION "3.0.1301.101"

    SQL Server "Microsoft SQL Server" VERSION "10.50.1600"

     

    Stacktrace at the point of stop()ping:
        at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.6.0_23]
        at java.net.SocketInputStream.read(Unknown Source) ~[na:1.6.0_23]
        at com.microsoft.sqlserver.jdbc.TDSChannel.read(IOBuffer.java:1647) ~[jdbc4-driver-3.0.jar:na]
        at com.microsoft.sqlserver.jdbc.TDSReader.readPacket(IOBuffer.java:3694) ~[jdbc4-driver-3.0.jar:na]
        at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.ensureSSLPayload(IOBuffer.java:602) ~[jdbc4-driver-3.0.jar:na]
        at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.readInternal(IOBuffer.java:664) ~[jdbc4-driver-3.0.jar:na]
        at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.read(IOBuffer.java:656) ~[jdbc4-driver-3.0.jar:na]
        at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.readInternal(IOBuffer.java:851) ~[jdbc4-driver-3.0.jar:na]
        at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.read(IOBuffer.java:839) ~[jdbc4-driver-3.0.jar:na]
        at com.sun.net.ssl.internal.ssl.InputRecord.readFully(Unknown Source) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[na:1.6]
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[na:1.6]
        at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1483) ~[jdbc4-driver-3.0.jar:na]
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1042) ~[jdbc4-driver-3.0.jar:na]
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:817) ~[jdbc4-driver-3.0.jar:na]
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:700) ~[jdbc4-driver-3.0.jar:na]
        at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:842) ~[jdbc4-driver-3.0.jar:na]
        at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.6.0_23]
        at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.6.0_23]

     

    This problem seems to only occur at a combination of SQL server 2008 / JDBC driver 3.0, presumably because even when connections are not specifically done through SSL, by default the authentication step always is. So reverting to either SQL 2005 or JDBC 2.0 means the code path bypasses this code. As might using integratedSecurity=True (not tested). However, this is only a limited workaround that we cannot ask from our customers.

     

    My question are:

    Why does this thread not time-out according to the loginTimeout property ?

    Can this be prevented from happening in any other way than reverting driver or SQL server version ? Can authentication be forced to non-SSL through a property configuration ?

     

     




    Monday, October 24, 2011 11:49 AM

All replies

  • Hi Niels van Klaveren,

    What is the connection string? If the server is not installed a certificate, please set encrypt option to false on the connection string. For more information: Connecting to SQL Server with the JDBC Driver

    Best Regards,
    Stephanie Lv


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Wednesday, October 26, 2011 7:20 AM
  •  

    The connection string is a very basic jdbc:sqlserver://localhost:1433. SSL is not used for encrypting communication, but is enabled for SQL authentication by default on an SQL 2008(R2) / JDBC driver 3.0 combination, after which communication for normal SQL falls back to non-SSL. This SSL authentication only behaviour cannot be disabled as far as I know.

    That's the part where things go wrong. We haven't seen this problem occur on 2005 / JDBC 3.0, because SSL authentication is not used by default on the server, or on 2008(R2) / JDBC 2.0 because it is not used by default in the driver.

    Also, this problem occurs intermittently. Most connections work normally. Only some newly created connections 'hang' this way. A socket connection has been made, but it seems the loginTimeout parameter in SQL server is used only for timing out on acquiring a socket, but a connection is only useable after successful login, and as such, the loginTimeout should include the authentication process, which it doesn't, and should be considered a bug.

    See also http://social.msdn.microsoft.com/Forums/en-US/sqldataaccess/thread/97dce8fd-6487-4bca-80b0-492167db3e0d , where a recently introduced Java bug makes the JDBC 3.0 SQL connection 'hang' indefinitely in authentication with an SQL2008R2 server every single time. The driver should time this out, but doesn't for exactly the same reason. The socket is acquired, but the authentication step gets into an infinite loop, and should (at least) be broken out of that by the loginTimeout, resulting in an exception.





    Thursday, October 27, 2011 8:40 AM
  • Hi Niels,

    having a similar problem here.

    But the behavior is not intermittent with me. I can always reproduce it on jre versions 6u29 and 6u30ea.

    In 6u26 and before and in 7u1 the problem never happens. I submitted a bug report at oracle with a log from the jdbc driver and a stacktrace of the deadlock. It seems, Oracle introduced a different behavior in latest Java6-JREs.

    Please post new findings here. I will also.

    regards

    Reinhard

     

    Bug ID: (not online yet as I write this, maybe in 1-2 days)

    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7106332

    Saturday, October 29, 2011 12:50 PM
  • This is NOT the exact same problem as the Java 1.6.0_29 bug. It also happens (intermittently) on other Java builds. In both situations something goes wrong with the (SSL) authentication, in the first situation this is caused by Java, in the second one, no one knows.

     

    The underlying problem to both issues is the fact that the loginTimeout period in the JDBC driver doesn't actually time out if something goes wrong during authentication. It only times out acquiring the socket connection. The JDBC team should actually have the driver time out the connection when it isn't ready to accept queries within the loginTimeout parameter (15 secs default), even if no exceptions are thrown.


    Tuesday, November 15, 2011 2:18 PM