FULL PRODUCT VERSION :
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
I think is is not related to OS, but to Java Code.
SunOS 5.11 11.2 sun4v sparc sun4v
A DESCRIPTION OF THE PROBLEM :
There is a problem in SerialBlob setBytes(long pos, byte[] bytes, int offset, int length) method. The condition which decides if bytes should be added to Blob is:
while ( i < length || (offset + i +1) < (bytes.length-offset) )
In my opinion || should be replaced by &&. If we send a big buffer and we tell to read from the beginning (offset=0) but only a few elements (length < bytes.length), all the bytes are indeed written, but then it crashes - it wants to write even when the internal buffer is smaller! The condition (i < length) says that we already wrote all we wanted and the loop should be finished. In reality the second part of the condition forces loop to continue which causes ArrayIndexOutOfBoundsException. I think (i < length) should be critical and break the loop.
Why implementation does not use just System.arraycopy?
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No error, bytes should be copied to SerialBlob
ACTUAL -
java.lang.ArrayIndexOutOfBoundsException: 10
at javax.sql.rowset.serial.SerialBlob.setBytes(SerialBlob.java:378)
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ArrayIndexOutOfBoundsException: 10
at javax.sql.rowset.serial.SerialBlob.setBytes(SerialBlob.java:378)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
try {
byte[] source = new byte[10];
Blob blob = new SerialBlob(new byte[source.length]);
ByteArrayInputStream inputStream = new ByteArrayInputStream(source);
int BUFFER_SIZE = 3;
byte[] buffer = new byte[BUFFER_SIZE];
int read, lastInsert = 1;
read = inputStream.read(buffer, 0, BUFFER_SIZE);
while (read != -1) {
blob.setBytes(lastInsert, buffer, 0, read);
lastInsert += read;
read = inputStream.read(buffer, 0, BUFFER_SIZE);
}
inputStream.close();
}catch (Exception e){
e.printStackTrace();
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
try {
byte[] source = new byte[10];
Blob blob = new SerialBlob(new byte[source.length]);
ByteArrayInputStream inputStream = new ByteArrayInputStream(source);
int BUFFER_SIZE = 3;
byte[] buffer = new byte[BUFFER_SIZE];
int read, lastInsert = 1;
read = inputStream.read(buffer, 0, BUFFER_SIZE);
boolean changeBuffer = false;
while (read != -1) {
if (read != BUFFER_SIZE) {
/*needed because of bugged(?) blob.setBytes*/
byte[] buffer2 = new byte[read];
System.arraycopy(buffer, 0, buffer2, 0, read);
buffer = buffer2;
changeBuffer = true;
}
blob.setBytes(lastInsert, buffer, 0, read);
lastInsert += read;
if (changeBuffer) {
buffer = new byte[BUFFER_SIZE];
changeBuffer = !changeBuffer;
}
read = inputStream.read(buffer, 0, BUFFER_SIZE);
}
inputStream.close();
}catch (Exception e){
e.printStackTrace();
}
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
I think is is not related to OS, but to Java Code.
SunOS 5.11 11.2 sun4v sparc sun4v
A DESCRIPTION OF THE PROBLEM :
There is a problem in SerialBlob setBytes(long pos, byte[] bytes, int offset, int length) method. The condition which decides if bytes should be added to Blob is:
while ( i < length || (offset + i +1) < (bytes.length-offset) )
In my opinion || should be replaced by &&. If we send a big buffer and we tell to read from the beginning (offset=0) but only a few elements (length < bytes.length), all the bytes are indeed written, but then it crashes - it wants to write even when the internal buffer is smaller! The condition (i < length) says that we already wrote all we wanted and the loop should be finished. In reality the second part of the condition forces loop to continue which causes ArrayIndexOutOfBoundsException. I think (i < length) should be critical and break the loop.
Why implementation does not use just System.arraycopy?
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No error, bytes should be copied to SerialBlob
ACTUAL -
java.lang.ArrayIndexOutOfBoundsException: 10
at javax.sql.rowset.serial.SerialBlob.setBytes(SerialBlob.java:378)
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ArrayIndexOutOfBoundsException: 10
at javax.sql.rowset.serial.SerialBlob.setBytes(SerialBlob.java:378)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
try {
byte[] source = new byte[10];
Blob blob = new SerialBlob(new byte[source.length]);
ByteArrayInputStream inputStream = new ByteArrayInputStream(source);
int BUFFER_SIZE = 3;
byte[] buffer = new byte[BUFFER_SIZE];
int read, lastInsert = 1;
read = inputStream.read(buffer, 0, BUFFER_SIZE);
while (read != -1) {
blob.setBytes(lastInsert, buffer, 0, read);
lastInsert += read;
read = inputStream.read(buffer, 0, BUFFER_SIZE);
}
inputStream.close();
}catch (Exception e){
e.printStackTrace();
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
try {
byte[] source = new byte[10];
Blob blob = new SerialBlob(new byte[source.length]);
ByteArrayInputStream inputStream = new ByteArrayInputStream(source);
int BUFFER_SIZE = 3;
byte[] buffer = new byte[BUFFER_SIZE];
int read, lastInsert = 1;
read = inputStream.read(buffer, 0, BUFFER_SIZE);
boolean changeBuffer = false;
while (read != -1) {
if (read != BUFFER_SIZE) {
/*needed because of bugged(?) blob.setBytes*/
byte[] buffer2 = new byte[read];
System.arraycopy(buffer, 0, buffer2, 0, read);
buffer = buffer2;
changeBuffer = true;
}
blob.setBytes(lastInsert, buffer, 0, read);
lastInsert += read;
if (changeBuffer) {
buffer = new byte[BUFFER_SIZE];
changeBuffer = !changeBuffer;
}
read = inputStream.read(buffer, 0, BUFFER_SIZE);
}
inputStream.close();
}catch (Exception e){
e.printStackTrace();
}
- csr for
-
JDK-8273683 Cannot setBytes() if incoming buffer's length is bigger than number of elements we want to insert.
-
- Closed
-
- duplicates
-
JDK-8279341 unexpected StringIndexOutOfBoundsException in javax.sql.rowset.serial.SerialClob
-
- Closed
-