Hello, back in 2011 there was a discussion about the new changed behavior of FilterOutputStream (and BufferedOutputStream) in regards to not anymore swalloging IOExceptions from flush() on this list (thats where I got the subject from).
This was generally a very good improvement (and I am glad that https://bugs.openjdk.java.net/browse/JDK-6335274 thereby got fixed). However the implementation with the try-with-resource has a problem: when flush() and close() report the same exception instance the construction of the suppressed exception will actually fail with an IllegalArgumentException. This IllegalArgumentException of Throwable.addSuppressed is very unfortunate (it would be better simply ignore it). Anyway, this new behavior broke a Unit-Test for Apache VFS as you can see here: https://issues.apache.org/jira/browse/VFS-521 I think this can only be fixed in Throwable by avoiding this IllegalArgumentException or by the close() method not using try-with-resource. For reference, according to this changeset other locations are affected as well: http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/759aa847dcaf Gruss Bernd PS: I wrote a german blogpost about the FilterOutputStream here: http://itblog.eckenfels.net/archives/505-FOS-considered-harmfull.html The following exception is produced by the testcode: Exception in thread "main" java.lang.IllegalArgumentException: Self-suppression not permitted at java.lang.Throwable.addSuppressed(Throwable.java:1043) at java.io.FilterOutputStream.close(FilterOutputStream.java:159) at testfos.Main.main(Main.java:6) Caused by: java.io.IOException: remebered IO Exception at testfos.FailingOS.<init>(FailingOS.java:10) at testfos.Main.main(Main.java:5) package testfos; public class Main { public static void main(String[] args) throws java.io.IOException { java.io.BufferedOutputStream buf = new java.io.BufferedOutputStream(new testfos.FailingOS()); buf.close(); // expected: IOException } } package testfos; public class FailingOS extends java.io.OutputStream { private java.io.IOException ex; public FailingOS() { ex = new java.io.IOException("remebered IO Exception"); } public void write(int b) throws java.io.IOException { } public void flush() throws java.io.IOException { throw ex; } public void close() throws java.io.IOException { throw ex; } }
