Description:
Sometimes, not always, but always using Compression with Connector/J, the driver crash when the query report some records with a GEOMETRY/BLOB field and its size is very big ( >10MBytes ). In this case, in the method
private void getNextPacketIfRequired(int numBytes) throws IOException{
if ((this.buffer == null)
|| ((this.pos + numBytes) > this.buffer.length)) {
getNextPacketFromServer();
}
}
only one packet from server is read. In some case, it's need read more than one packet because a System.arraycopy fails.
24/04/07 16:56:38 ERROR: OraSQLIterator.iterame:: Message:Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.lang.ArrayIndexOutOfBoundsException
STACKTRACE:
java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at com.mysql.jdbc.CompressedInputStream.read(CompressedInputStream.java:286)
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1960)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2428)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2874)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:868)
at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1351)
at com.mysql.jdbc.RowDataDynamic.nextRecord(RowDataDynamic.java:367)
at com.mysql.jdbc.RowDataDynamic.next(RowDataDynamic.java:354)
at com.mysql.jdbc.ResultSet.next(ResultSet.java:7330)
at ** END NESTED EXCEPTION **
Last packet sent to the server was 15 ms ago.
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.lang.ArrayIndexOutOfBoundsException
STACKTRACE:
java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at com.mysql.jdbc.CompressedInputStream.read(CompressedInputStream.java:286)
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1960)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2428)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2874)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:868)
at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1351)
at com.mysql.jdbc.RowDataDynamic.nextRecord(RowDataDynamic.java:367)
at com.mysql.jdbc.RowDataDynamic.next(RowDataDynamic.java:354)
at com.mysql.jdbc.ResultSet.next(ResultSet.java:7330)
at ** END NESTED EXCEPTION **
Last packet sent to the server was 15 ms ago.
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2880)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:868)
at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1351)
at com.mysql.jdbc.RowDataDynamic.nextRecord(RowDataDynamic.java:367)
at com.mysql.jdbc.RowDataDynamic.next(RowDataDynamic.java:354)
at com.mysql.jdbc.ResultSet.next(ResultSet.java:7330)
======================================================
How to repeat:
create a table with geometry field and fill with large geometries. Make a preparedStatement querying all records.
Suggested fix:
To change the method to check if it's needed to read more than one packet from server.
CompressedInputStream.java:233
private void getNextPacketIfRequired(int numBytes) throws IOException {
int i=0;
while((this.buffer == null) || ((this.pos + numBytes) > this.buffer.length)) {
getNextPacketFromServer();
}
}