aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcgdecker <cgdecker@google.com>2015-01-21 08:55:41 -0800
committerColin Decker <cgdecker@google.com>2015-01-21 14:25:34 -0500
commit386a2fb1569b81a31e245e88e4792607bfaee980 (patch)
tree005d58311337581eb63a677aed027fc874e2c32f
parent5fcb8799da03b9d4add5c9d0f9b8016e6f61677f (diff)
downloadjimfs-386a2fb1569b81a31e245e88e4792607bfaee980.tar.gz
Change JimfsOutputStream.flush() to do nothing rather than throw an exception when the stream is already already closed.
This matches the behavior of other core OutputStream implementations such as that returned by Files.newOutputStream(Path) for the default FileSystem and prevents an exception when nesting an OutputStream inside a BufferedOutputStream inside an OutputStreamWriter using try-with-resources under JDK8 (among any number of other situations that could cause the same problem). (Details: try-with-resources closes each declared resource in reverse order. Closing the OutputStreamWriter causes the BufferedOutputStream to be closed which causes the unbuffered OutputStream to be flushed and then closed. Closing the BufferedOutputStream then tries to flush the unbuffered OutputStream again. Prior to JDK8, any exception thrown by this flush() was swallowed and completely ignored; in JDK8, the behavior changed to (correctly) throw that exception.) ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=84439059
-rw-r--r--jimfs/src/main/java/com/google/common/jimfs/JimfsOutputStream.java8
-rw-r--r--jimfs/src/test/java/com/google/common/jimfs/JimfsOutputStreamTest.java29
2 files changed, 24 insertions, 13 deletions
diff --git a/jimfs/src/main/java/com/google/common/jimfs/JimfsOutputStream.java b/jimfs/src/main/java/com/google/common/jimfs/JimfsOutputStream.java
index 0755489..a79809c 100644
--- a/jimfs/src/main/java/com/google/common/jimfs/JimfsOutputStream.java
+++ b/jimfs/src/main/java/com/google/common/jimfs/JimfsOutputStream.java
@@ -89,12 +89,6 @@ final class JimfsOutputStream extends OutputStream {
}
}
- @Override
- public synchronized void flush() throws IOException {
- checkNotClosed();
- // writes are synchronous to the file, so flush does nothing
- }
-
private void checkNotClosed() throws IOException {
if (file == null) {
throw new IOException("stream is closed");
@@ -115,4 +109,4 @@ final class JimfsOutputStream extends OutputStream {
private boolean isOpen() {
return file != null;
}
-} \ No newline at end of file
+}
diff --git a/jimfs/src/test/java/com/google/common/jimfs/JimfsOutputStreamTest.java b/jimfs/src/test/java/com/google/common/jimfs/JimfsOutputStreamTest.java
index cf3363b..cddd118 100644
--- a/jimfs/src/test/java/com/google/common/jimfs/JimfsOutputStreamTest.java
+++ b/jimfs/src/test/java/com/google/common/jimfs/JimfsOutputStreamTest.java
@@ -18,6 +18,7 @@ package com.google.common.jimfs;
import static com.google.common.jimfs.TestUtils.bytes;
import static com.google.common.jimfs.TestUtils.regularFile;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.fail;
@@ -27,7 +28,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import java.io.BufferedOutputStream;
import java.io.IOException;
+import java.io.OutputStreamWriter;
/**
* Tests for {@link JimfsOutputStream}.
@@ -158,15 +161,29 @@ public class JimfsOutputStreamTest {
} catch (IOException expected) {
}
- try {
- out.flush();
- fail();
- } catch (IOException expected) {
- }
-
out.close(); // does nothing
}
+ @Test
+ public void testClosedOutputStream_doesNotThrowOnFlush() throws IOException {
+ JimfsOutputStream out = newOutputStream(false);
+ out.close();
+ out.flush(); // does nothing
+
+ try (JimfsOutputStream out2 = newOutputStream(false);
+ BufferedOutputStream bout = new BufferedOutputStream(out2);
+ OutputStreamWriter writer = new OutputStreamWriter(bout, UTF_8)) {
+ /*
+ * This specific scenario is why flush() shouldn't throw when the stream is already closed.
+ * Nesting try-with-resources like this will cause close() to be called on the
+ * BufferedOutputStream multiple times. Each time, BufferedOutputStream will first call
+ * out2.flush(), then call out2.close(). If out2.flush() throws when the stream is already
+ * closed, the second flush() will throw an exception. Prior to JDK8, this exception would be
+ * swallowed and ignored completely; in JDK8, the exception is thrown from close().
+ */
+ }
+ }
+
private static JimfsOutputStream newOutputStream(boolean append) {
RegularFile file = regularFile(0);
return new JimfsOutputStream(file, append, new FileSystemState(Runnables.doNothing()));