-
Bug
-
Resolution: Fixed
-
P3
-
1.4.1
-
rc
-
x86
-
windows_nt
-
Verified
Name: rmT116609 Date: 06/26/2002
FULL PRODUCT VERSION :
java version "1.4.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-beta-b14)
Java HotSpot(TM) Client VM (build 1.4.1-beta-b14, mixed mode)
FULL OPERATING SYSTEM VERSION :
Windows NT Version 4.0 Service Pack 6a
A DESCRIPTION OF THE PROBLEM :
When an arbitrary (e.g. anonymous) ReadableByteChannel is
used with the transferFrom() method of a FileChannel, it
tries to transfer more data than was requested.
The buffer that is passed to the read() method of the
anonymous ReadableByteChannel has more data remaining that
was requested to be transferred, in the last block.
This used to work in 1.4.0 and 1.4.0_01, but is now broken
(note that 1.4.0 has a multitude of other problems related
to this method, including crashing the JVM, that seem to be
fixed now).
REGRESSION. Last worked in version 1.4
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the example code.
2. Run it, e.g. java TransferBugTest
3. Watch the output.
EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected results (this works in JDK 1.4.0):
The last lines of output should say:
array.length = 131077, writePosition = 131072, writeLength
= 5
count = 131077
Actual results (this breaks in JDK 1.4.1 beta):
Instead you get:
array.length = 131077, writePosition = 131072, writeLength
= 8192
Exception in thread "main"
java.lang.IndexOutOfBoundsException
at java.nio.Buffer.checkBounds(Buffer.java:454)
at java.nio.DirectByteBuffer.put
(DirectByteBuffer.java:292)
at TransferBugTest$1.read(TransferBugTest.java:28)
at
sun.nio.ch.FileChannelImpl.transferFromArbitraryChannel
(FileChannelImpl.java:534)
at sun.nio.ch.FileChannelImpl.transferFrom
(FileChannelImpl.java:572)
at TransferBugTest.main(TransferBugTest.java:18)
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.IndexOutOfBoundsException
at java.nio.Buffer.checkBounds(Buffer.java:454)
at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:292)
at TransferBugTest$1.read(TransferBugTest.java:28)
at sun.nio.ch.FileChannelImpl.transferFromArbitraryChannel
(FileChannelImpl.java:534)
at sun.nio.ch.FileChannelImpl.transferFrom(FileChannelImpl.java:572)
at TransferBugTest.main(TransferBugTest.java:18)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.RandomAccessFile;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
public class TransferBugTest
{
public static void main(String[] args)
throws IOException
{
RandomAccessFile file = new RandomAccessFile("test.dat", "rw");
file.setLength(131077);
FileChannel channel = file.getChannel();
final byte[] array = new byte[131077];
long count = channel.transferFrom(new ReadableByteChannel()
{
public int read(ByteBuffer buffer)
{
int writeLength = buffer.remaining();
System.out.println("array.length = " + array.length +
", writePosition = " + writePosition +
", writeLength = " + writeLength);
buffer.put(array, writePosition, writeLength);
writePosition += writeLength;
return writeLength;
}
public void close() {}
public boolean isOpen() { return true; }
private int writePosition = 0;
},
0,
131077);
System.out.println("count = " + count);
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
None, really.
If you know the number of bytes that should be transferred,
you can check the number of bytes remaining inside the read
() method. In general this is not possible of course,
because the only information being passed as arguments to
the ReadableByteChannel is the ByteBuffer, and even the
specification says it should try to read as much data that
is remaining in the buffer.
Release Regression From : 1.4.0_01
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.
(Review ID: 158461)
======================================================================