IndexOutOfBoundsException thrown by java.nio bytebuffer.put(byte[] arsrc, int offset , int length)
-
12-11-2019 - |
Вопрос
Hello all I hope someone can help me resolve this issue..
I'm curious as to why I'm getting this runtime error when from my perspective I shouldn't here's the code section:
// Send Message to the Message Log
public static void SendMesg()
{
String mesg_str = message_data.toString() ;
int msgstr_len = mesg_str.length(); // determine actual message length
int array_len = mesgwork.length ; // determine actual mesgwork array length
dt_stamp = getDateTime() ;
System.out.println(dt_stamp) ;
System.out.println( " LU62XnsCvr Diagnostic:");
System.out.println(" LU62XCI0100: Method = SendMesg") ;
System.out.println(" Message to be sent: " ) ;
System.out.println(mesg_str) ;
System.out.println("mesg_str Length=") ;
System.out.println(msgstr_len) ;
System.out.println("Derived mesgwork Length=") ;
System.out.println(array_len) ;
System.out.println("Class Var MGBuffer length value: ") ;
System.out.println(MGBUFLN) ;
System.out.println("Buffer Offset Value=") ;
System.out.println(bufroffset) ;
System.out.println( " LU62XnsCvr End Diagnostic") ;
mesgwork = mesg_str.getBytes() ; //Convert msg string to byte array
mesg_bufr.put( mesgwork, bufroffset, MGBUFLN ) ;// <= error occurs here
pgm_cntl = WRITE_MESG ;
FileControl() ;
if (pgm_cntl == WRITE_ERROR)
{
sys_return = pgm_cntl ;
SysEnd( sys_return ) ;
}
mesgcount = mesgcount + 1 ; // increment the message counter
mesg_bufr.clear() ;
message_data.append(" ") ; // 16 bytes of blanks
clearByteArray( mesgwork, MGBUFLN ) ;
} // End of Send Message log write sub-routine
This is what's displayed when I run the program:
2011.05.12 10:48:07
LU62XnsCvr Diagnostic:
LU62XCI0100: Method = SendMesg
Message to be sent:2011.05.12 10:48:07 LU62XCE0313: CPIC Return Code =1 CM Alloc ConversationID=[B@201d201d
mesg_str Length=89
Derived mesgwork Length=192
Class Var MGBuffer length value:192
Buffer Offset Value=0
LU62XnsCvr End Diagnostic
Exception in thread "main" java.lang.IndexOutOfBoundsException
at java.nio.Buffer.checkBounds(Buffer.java:543)
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:177)
at APPC_LU62.Runtime.LU62XnsCvr.SendMesg(LU62XnsCvr.java:652)
at APPC_LU62.Runtime.LU62XnsCvr.StartConvrs(LU62XnsCvr.java:517)
at APPC_LU62.Runtime.LU62XnsCvr.ProcessRqsts(LU62XnsCvr.java:398)
at APPC_LU62.Runtime.LU62XnsCvr.main(LU62XnsCvr.java:357)
here's integer variable MGBUFLN declared prior to any reference to it within LU62XnsCvr Class
final static int MGBUFLN = 192 ; //Message Buffer Length
here's the byte array that's used as the "source" declared as a LU62XnsCvr Class member variable...
static byte[] mesgwork = new byte[MGBUFLN] ;
This I copied from the Oracle Java Doc website; don't know exactly how current it is,
but it's marked as java 6 and I'm running IBM's SDK which is using java 1.6
public ByteBuffer put(byte[] src, int offset, int length)
Relative bulk put method (optional operation). This method transfers bytes into this buffer from the given source array. If there are more bytes to be copied from the array than remain in this buffer, that is, if length > remaining(), then no bytes are transferred and a BufferOverflowException is thrown. Otherwise, this method copies length bytes from the given array into this buffer, starting at the given offset in the array and at the current position of this buffer. The position of this buffer is then incremented by length. In other words, an invocation of this method of the form
dst.put(src, off, len)
has exactly the same effect as the loopfor (int i = off; i < off + len; i++) dst.put(a[i]);
except that it first checks that there is sufficient space in this buffer and it is potentially much more efficient.
Parameters:
- src - The array from which bytes are to be read
- offset - The offset within the array of the first byte to be read; must be non-negative and no larger than array.length
- length - The number of bytes to be read from the given array; must be non-negative and no larger than array.length - offset
Returns: This buffer
Throws:
- BufferOverflowException - If there is insufficient space in this buffer
- IndexOutOfBoundsException - If the preconditions on the offset and length parameters do not hold
- ReadOnlyBufferException - If this buffer is read-only
I'm a little concerned with the statements:
Otherwise, this method copies length bytes from the given array into this buffer, starting at the given offset in the array and at the current position of this buffer. The position of this buffer is then incremented by length.
and then:
except that it first checks that there is sufficient space in this buffer and it is potentially much more efficient.
// * my additional comments * //
Now I want to completely "fill" the 192 byte buffer (index therefore ranges from 0 - 191)
So IF as is put forth in the doc, the buffer is "incremented" by the length
(192 bytes in this case)
then it appears to me by implication the "logic" is going to add 192 bytes to index and
low and behold ... we're out of bounds on the index ...
I'd really appreciate anyone's opinion on this.
Waiting for your comments and/or suggestions...
Thanks
Guy
Решение
In the line
mesg_bufr.put( mesgwork, bufroffset, MGBUFLN ) ;
you are trying to transfer MGBUFLN (ie 192) bytes from the mesgwork byte array to the buffer. But your mesgwork array has only 89 bytes in it, which is why you are getting the out of bounds exception.
try this:
mesg_bufr.put( mesgwork, bufroffset, mesgwork.length ) ;
Другие советы
mesgwork
is an array that contains less elements than bufroffset + MGBUFLN
Since you initialize your array with size = MGBULFN
, then I would assume your bufferoffset
must be always 0 in order for this to work.
Apart from that - MGBULFN
is a rather cryptic name for a constant. Consider renaming it.