Nathan, thanks a lot for reporting this. Sorry no one has replied to you earlier, but your bug report was actually entered into the JBS (JDK Bug System):
https://bugs.openjdk.java.net/browse/JDK-8054565 So don't worry, it won't get lost. Now about the issue itself. It's indeed a bug. Though methods should be written in an atomic fashion [1] (where possible and where it makes sense), you are right -- java.io.Closeable#close is certainly not one of these methods. There is nothing you can do if 'close' fails. This method has a terminal semantics. Implementations cannot rely on some external retry strategy. java.io.Closeable#close should be called at most once in a lifetime of a Closeable object. I skimmed through the JDK sources and found some more examples of this behaviour. They should be fixed as well. As for this particular issue, I see two options: 1. We just fix it and that's it 2. You sign OCA [2], provide a test, prepare a change review and if everything is fine we push it with comment 'Contributed-by: nathan.a.clem...@hotmail.com' (or whatever email you choose) --------------------------------------------------------------------------------- [1] Effective Java, Second Edition, Item 64: Strive for failure atomicity [2] http://openjdk.java.net/contribute/ -Pavel > On 2 Dec 2014, at 23:36, Nathan Clement <nathan.a.clem...@hotmail.com> wrote: > > Hi, > > I have encountered a bug in FilterOutputStream under Java 8. The bug is that > calling close() on the same stream twice can now result in an exception, > whereas under Java 7 it did not. The reason is that > FilterOutputStream.close() calls flush() before calling close() on the > underlying stream. Calling close() twice on the FilterOutputStream will thus > result in flush() being called twice. Some streams (such as > OracleBlobOutputStream) will throw an exception if flush() is called after > the stream is closed. In Java 7 any exceptions when calling flush() were > ignored, but in Java 8 these exceptions are passed on to the caller. > > This bug appears to have been introduced in "7015589: (spec) > BufferedWriter.close leaves stream open if close of underlying Writer fails". > The FilterOutputStream.close() method now does not obey the contract of > AutoClosable.close(): "If the stream is already closed then invoking this > method has no effect." > > Some sample code that illustrates the problem: > > try( InputStream bis = new BufferedInputStream( inputStream ); > OutputStream outStream = payloadData.setBinaryStream( 0 ); > BufferedOutputStream bos = new BufferedOutputStream( outStream ); > DeflaterOutputStream deflaterStream = new DeflaterOutputStream( > bos, new Deflater( 3 ) ) ) > { > fileSize = IOUtil.copy( bis, deflaterStream ); > } > The try-with-resources mechanism will call close on the DeflaterOutputStream, > which will in turn call close on the BufferedOutputStream, which will call > flush() then close() on the blob output stream. The try-with-resources > mechanism will then call close on the BufferedOutputStream which again calls > flush() on the blob output stream, resulting in an exception. > > My proposed fix is to change FilterOutputStream.close() as follows: > > @Override > @SuppressWarnings("try") > public void close() throws IOException { > if (!closed) { > closed = true; > try (OutputStream ostream = out) { > flush(); > } > } > } > > private boolean closed = false; > > This will prevent flush() being called on an already closed stream. > > I have reported this issue via the Oracle bug tracker and got Review ID > JI-9014085, however I never received any follow up from Oracle. I have also > discussed the issue on Stack Overflow: > http://stackoverflow.com/questions/25175882/java-8-filteroutputstream-exception. > Do people agree that this is a bug? If so, what is the process for fixing > it? > > Thanks, > > Nathan Clement >