Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6448457
Votes 2
Synopsis (ch) Channels.newOutputStream().write() does not write all data
Category java:classes_nio
Reported Against
Release Fixed 7(b25), 5.0u16-rev(b07) (Bug ID:2153750) , 1.4.2_18-rev(b08) (Bug ID:2157730) , 5.0u17(b02) (Bug ID:2168688) , 1.4.2_19(b01) (Bug ID:2168772)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 6600423
Submit Date 13-JUL-2006
Description
FULL PRODUCT VERSION :
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_06-b05, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux rhap-grid1 2.6.5-7.97-smp #1 SMP Fri Jul 2 14:21:59 UTC 2004 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
The implementation of the OutputStream returned by Channels.newOutputStream() ignores the return code from the underlying channel and hence does not write all the data if the channel performs short writes.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1/ Let the WritableByteChannel be:

public class SillyWritableByteChannel implements WritableByteChannel {
    public int write(ByteBuffer src) throws IOException {
        if(src.remaining() > 0) {
            System.out.println( src.get() );
            return 1;
        }
        return 0;
    }

    public void close() throws IOException {
    }

    public boolean isOpen() {
        return true;
    }
}

2/ If the above channel is passed to Channels.newOutputStream() and a byte array of length > 1 passed to the write method, only the first byte will be written.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
All bytes should be written according to the OutputStream contract.
ACTUAL -
The number of bytes written in the first call to WritableByteChannel.write() are written.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import java.util.Random;

import junit.framework.TestCase;

public class ChannelsNewOutputStreamTest extends TestCase {
	
	public void testWrite() throws Exception {
		Random random = new Random();
		byte[] data = new byte[8192];
		random.nextBytes(data);
		
		SillyWritableByteChannel writableByteChannel = new SillyWritableByteChannel();
		OutputStream outputStream = Channels.newOutputStream(writableByteChannel);
		outputStream.write(data);
		assertEquals(data.length, writableByteChannel.getNumBytesWritten());
	}
	
	static class SillyWritableByteChannel implements WritableByteChannel {
		private int numBytesWritten = 0;
		
	    public int write(ByteBuffer src) throws IOException {
	        if(src.remaining() > 0) {
	            src.get();
	            this.numBytesWritten++;
	            return 1;
	        }
	        return 0;
	    }

	    public void close() throws IOException {
	    	;
	    }

	    public boolean isOpen() {
	        return true;
	    }
	    
	    public int getNumBytesWritten() {
	    	return this.numBytesWritten;
	    }
	}
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Do not use Channels.newOutputStream().
Posted Date : 2006-07-13 11:18:54.0
Work Around
N/A
Evaluation
As the channel, depending on its type and state, may only write some (or none) of the requested bytes then this case must be handled so as to implement the OutputStream contract.
Posted Date : 2007-09-04 11:18:18.0
Comments
  
  Include a link with my name & email   

Submitted On 03-NOV-2006
basdebakker
This behaviour can also occur with a FileChannel. If the disk is almost full, FileChannel.write() will write only part of the buffer. This is agains the WritableByteChannel specification quoted in the Evaluation, but still happens (at least on my Linux system).



PLEASE NOTE: JDK6 is formerly known as Project Mustang