Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
FULL PRODUCT VERSION : A DESCRIPTION OF THE PROBLEM : The change for Bug ID 7015589 included a change to FilterOutputStream so that it does not swallow exceptions when calling flush: http://hg.openjdk.java.net/hsx/hotspot-rt/jdk/rev/759aa847dcaf public void close() throws IOException { try (OutputStream ostream = out) { flush(); } } The problem is that if close() is called a second time, flush() will be called on the underlying stream after it has already been closed. Many underlying streams will throw an exception in this case. The implementation of FilterOutputStream.close() should be changed so that it follows the contract of Closeable: "Closes this stream and releases any system resources associated with it. If the stream is already closed then invoking this method has no effect." One possible implementation idea is to introduce a member variable to track whether the stream has already been closed: public void close() throws IOException { if (!closed) { closed = true; try (OutputStream ostream = out) { flush(); } } } See http://stackoverflow.com/questions/25175882/java-8-filteroutputstream-exception/ REGRESSION. Last worked in version 7u67 STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Run the attached test program EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - No exception is thrown ACTUAL - Exception is thrown: Exception in thread "main" java.io.IOException: Stream closed at FilterOutputStreamTest$MockBlobOutputStream.flush(FilterOutputStreamTest.java:24) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:141) at java.io.FilterOutputStream.close(FilterOutputStream.java:158) at FilterOutputStreamTest.main(FilterOutputStreamTest.java:52) REPRODUCIBILITY : This bug can be reproduced always. ---------- BEGIN SOURCE ---------- import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; public class FilterOutputStreamTest { /** * This stream simulates a OracleBlobOutputStream which will throw * an exception if flush is called after close. */ static class MockBlobOutputStream extends ByteArrayOutputStream { private boolean closed; @Override public void flush() throws IOException { if (closed) { throw new IOException("Stream closed"); } } @Override public void close() throws IOException { closed = true; } } public static void main( final String[] args ) throws Exception { try( InputStream bis = new ByteArrayInputStream( "Hello".getBytes() ); OutputStream outStream = new MockBlobOutputStream(); BufferedOutputStream bos = new BufferedOutputStream( outStream ); DeflaterOutputStream deflaterStream = new DeflaterOutputStream( bos, new Deflater( 3 ) ) ) { int len = 0; final byte[] buf = new byte[1024]; while ((len = bis.read(buf)) >= 0) { if ( len > 0 ) { deflaterStream.write(buf,0,len); } } } } } ---------- END SOURCE ----------
|