diff options
-rw-r--r-- | harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterOutputStreamTest.java | 41 | ||||
-rw-r--r-- | ojluni/src/main/java/java/io/FilterOutputStream.java | 52 |
2 files changed, 90 insertions, 3 deletions
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterOutputStreamTest.java index 666955d8ca..cc5b91b771 100644 --- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterOutputStreamTest.java +++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FilterOutputStreamTest.java @@ -59,6 +59,47 @@ public class FilterOutputStreamTest extends TestCase { } /** + * java.io.FilterOutputStream#close_flushthrows() + */ + public void test_close_flushthrows() throws IOException { + class FakeOutputStream extends OutputStream { + + public int closedCount; + + @Override + public void close() throws IOException { + super.close(); + closedCount++; + } + + @Override + public void flush() throws IOException { + super.flush(); + throw new IOException("FakeOutputStream#flush() mocked exception"); + } + + @Override + public void write(int b) throws IOException { + } + } + + FakeOutputStream fos = new FakeOutputStream(); + os = new FilterOutputStream(fos); + os.write(42); + + try { + os.close(); + } + catch (IOException e) { + } + assertEquals("Underlying stream's close() called even if flush() throws", 1, + fos.closedCount); + + os.close(); + assertEquals("Underlying stream's close() called exactly once", 1, fos.closedCount); + } + + /** * java.io.FilterOutputStream#flush() */ public void test_flush() throws IOException { diff --git a/ojluni/src/main/java/java/io/FilterOutputStream.java b/ojluni/src/main/java/java/io/FilterOutputStream.java index 209e63b77c..89f5ef529b 100644 --- a/ojluni/src/main/java/java/io/FilterOutputStream.java +++ b/ojluni/src/main/java/java/io/FilterOutputStream.java @@ -48,6 +48,12 @@ class FilterOutputStream extends OutputStream { */ protected OutputStream out; + // Android-added: Integrate OpenJDK 9 fix for double-close. http://b/122733269. + /** + * Whether the stream is closed; implicitly initialized to false. + */ + private boolean closed; + /** * Creates an output stream filter built on top of the specified * underlying output stream. @@ -144,18 +150,58 @@ class FilterOutputStream extends OutputStream { * Closes this output stream and releases any system resources * associated with the stream. * <p> - * The <code>close</code> method of <code>FilterOutputStream</code> - * calls its <code>flush</code> method, and then calls the - * <code>close</code> method of its underlying output stream. + * When not already closed, the {@code close} method of {@code + * FilterOutputStream} calls its {@code flush} method, and then + * calls the {@code close} method of its underlying output stream. * * @exception IOException if an I/O error occurs. * @see java.io.FilterOutputStream#flush() * @see java.io.FilterOutputStream#out */ + // BEGIN Android-changed: Integrate OpenJDK 9 fix for double-close. http://b/122733269. + /* @SuppressWarnings("try") public void close() throws IOException { try (OutputStream ostream = out) { flush(); } } + */ + @Override + public void close() throws IOException { + if (closed) { + return; + } + closed = true; + + Throwable flushException = null; + try { + flush(); + } catch (Throwable e) { + flushException = e; + throw e; + } finally { + if (flushException == null) { + out.close(); + } else { + try { + out.close(); + } catch (Throwable closeException) { + // evaluate possible precedence of flushException over closeException + if ((flushException instanceof ThreadDeath) && + !(closeException instanceof ThreadDeath)) { + flushException.addSuppressed(closeException); + throw (ThreadDeath) flushException; + } + + if (flushException != closeException) { + closeException.addSuppressed(flushException); + } + + throw closeException; + } + } + } + } + // END Android-changed: Integrate OpenJDK 9 fix for double-close. http://b/122733269. } |