JDK-6957106 : (dc) DatagramChannel.write(ByteBuffer[]) limits array size to 16 rather than IOV_MAX
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 6u10
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2010-05-30
  • Updated: 2012-07-19
  • Resolved: 2012-07-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8Resolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04-248-10M3025)
Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01-101, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Mac OS X and Linux (read below for info)

A DESCRIPTION OF THE PROBLEM :
I first reported this to Apple since I found it on a Mac. They dismissed it though since they confirmed it to also exist on Linux. It's a pretty severe bug so I post it here for you. I haven't tested it on Linux (I have no box) but the answer from Apple was so thorough that I trust them.

---

DatagramChannel.write(ByteBuffer[]) silently discards all data in buffers with an index over 15. Only the first 16 elements are written, the rest are silently ignored.

This is a very serious problem since it is working in Windows and all Java applications which use more than 16 buffers will produce too small Datagrams.

The severity is that it is very hard to find the bug.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run example client code to reproduce the problem.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Obvious

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
try {
	DatagramChannel channel = DatagramChannel.open();
	channel.connect(new InetSocketAddress("localhost", 50000));
	channel.configureBlocking(true);
	channel.socket().setSendBufferSize(1000000);

	int bufferCount = 17; // Only works for 0-16.
	ByteBuffer[] buf = new ByteBuffer[bufferCount];
	for (int j = 0; j < bufferCount; j++)
		buf[j] = ByteBuffer.allocate(1);

	long wroteBytes = channel.write(buf);
	if (wroteBytes != bufferCount)
		System.out.println(wroteBytes + " != " + bufferCount);

} catch (IOException e) {
	e.printStackTrace();
}
---------- END SOURCE ----------

Comments
EVALUATION This issue has been fixed in 8 and 7u8 via 7176485.
19-07-2012

EVALUATION The implementation does indeed limit the number of buffers to 16. That is the value of IOV_MAX on Solaris. Other operating systems have their own limits but it shouldn't blindly impose a limit of 16. It is surprising to hear that anyone ran into this as usually the scatter/gather operations are used with a small number of buffers (2 or 3 usually). In order to fix this completely then we need to decide how DatagramChannel.write(ByteBuffer[]) should behave when invoked with more buffers than IOV_MAX. This may require a spec clarification.
31-07-2010