StringIndexOutOfBoundsException in ResponseStream.readString
Brought to you by:
ickzon
StringIndexOutOfBoundsException: String index out of range: -12032 at java.lang.String.checkBounds(Unknown Source) at java.lang.String.<init>(Unknown Source) at net.sourceforge.jtds.jdbc.ResponseStream.readString(ResponseStream.java:304) at net.sourceforge.jtds.jdbc.ResponseStream.readNonUnicodeString(ResponseStream.java:285) at net.sourceforge.jtds.jdbc.TdsData.readData(TdsData.java:961) at net.sourceforge.jtds.jdbc.TdsCore.tdsRowToken(TdsCore.java:3080) at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2347) at net.sourceforge.jtds.jdbc.TdsCore.clearResponseQueue(TdsCore.java:736) at net.sourceforge.jtds.jdbc.JtdsStatement.reset(JtdsStatement.java:722) at net.sourceforge.jtds.jdbc.JtdsStatement.close(JtdsStatement.java:966) at net.sourceforge.jtds.jdbc.JtdsConnection.close(JtdsConnection.java:2088) at net.sqweek.sql.SQL_DB.close(SQL_DB.java:181) at net.sqweek.sql.SQL_DB$1.run(SQL_DB.java:244) at java.lang.Thread.run(Unknown Source)
JTDS appears to have read -12032 as the string length. My code has a lot of concurrency on the JtdsConnection object - up to 16 threads accessing it at once. In this case the tcp connection appears to have physically dropped, so all 16 threads have likely called close() at once (while in the middle of iterating over results from a JtdsStatement).
The JtdsStatements themselves are not shared between threads.
Apologies if this is duplicated; I couldn't find anything with search but I also was unable to checkout from svn to check the commit history:
$ svn checkout http://svn.code.sf.net/p/jtds/code/trunk jtds-code svn: URL 'http://svn.code.sf.net/p/jtds/code/trunk' doesn't exist $ svn checkout http://svn.code.sf.net/p/jtds/trunk jtds-code svn: Server sent unexpected return value (403 Forbidden) in response to OPTIONS request for 'http://svn.code.sf.net/p/jtds/trunk'
Around line 961 of TdsData looks like this:
len = in.readShort();
if (len != -1) {
return in.readNonUnicodeString(len,
ci.charsetInfo == null ? connection.getCharsetInfo() : ci.charsetInfo);
}
Clearly you are getting a len of -12032, which is then causing the string bounds exception.
My suggestion would be that the criteria to read the string ought to be changed to:
if (len >= 0) {
...
}
because any negative number is ultimately going to result in the string bounds exception anyway. Better to just have this call fall through and return null. My guess on the cause is the abrupt TCP close, as you mentioned, generating some partial data.