JDK-8178845 : (bf) Need ByteBuffer.put(ByteBuffer) that transfers as many bytes as possible
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 8,9
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2017-04-14
  • Updated: 2020-12-16
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

A DESCRIPTION OF THE PROBLEM :
When I want to put bytes from one ByteBuffer to another ByteBuffer that is smaller or has less remaining() it throws an exception, that in my opinion is unnecessary.

For example: I make a ByteBuffer with the capacity of 64kb to read from a SocketChannel in a big chunk, and then want to move bytes from the ByteBuffer to a smaller ByteBuffer but i can't because of this bug.

I found a workaround, but under the hood it doesn't use System.arraycopy() and would be even slower if it was a direct ByteBuffer as it should get the bytes one by one, and in fact it is a lot slower to put bytes from say 1mb direct buffer to a 100kb direct buffer with this workaround then to use the ByteBuffer.put() method from a 100kb direct buffer to a 100kb direct buffer, i would use it but my application uses and normal and direct ByteBuffers, and this workaround is causing a significant performance issue.

I am sure it is not an OS specific problem, but i put the information just in case.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Put a bigger ByteBuffer into a smaller ByteBuffer.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I was expecting for the smaller ByteBuffer remaining bytes to be filled with the bigger ByteBuffer bytes until the smaller ByteBuffer would be full.
ACTUAL -
It doesn't fill the smaller ByteBuffer, it unfortunately just throws an exception

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.nio.BufferOverflowException
	at java.nio.HeapByteBuffer.put(Unknown Source)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.nio.ByteBuffer;

public class Main
{	
	public static void main(String[] args)
	{
		ByteBuffer one = ByteBuffer.allocate(5);
		ByteBuffer two = ByteBuffer.allocate(10);
		one.put(two);
	}
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
public class Main
{	
	public static void main(String[] args)
	{
		ByteBuffer one = ByteBuffer.allocate(5);
		ByteBuffer two = ByteBuffer.allocate(10);

		while(one.hasRemaining())
		{
			one.put(two.get());
		}
	}
}



Comments
A workaround available since JDK-8219014 was resolved is ByteBuffer src; ByteBuffer dst; dst.put(dst.position(), src, src.position(), Math.min(src.remaining(), dst.remaining())); but the suggested enhancement would still provide a convenience.
16-12-2020

This is not a bug, the methods work as specified. Instead, I think the submitter is looking for a relative put(ByteBuffer) that transfers as many bytes as possible. So changing this issue to an Enhancement.
17-04-2017