From 108bee17cfb13624030a405681701a412ed76676 Mon Sep 17 00:00:00 2001 From: Masaya Suzuki Date: Fri, 19 Aug 2016 13:51:05 -0700 Subject: [PATCH] Ignore IOException thrown from close AddCommandTest is flaky because IOException is thrown sometimes. Caused by: java.io.IOException: Stream closed at java.lang.ProcessBuilder$NullOutputStream.write(ProcessBuilder.java:433) at java.io.OutputStream.write(OutputStream.java:116) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) at java.io.FilterOutputStream.close(FilterOutputStream.java:158) at org.eclipse.jgit.util.FS.runProcess(FS.java:993) at org.eclipse.jgit.util.FS.execute(FS.java:1102) at org.eclipse.jgit.treewalk.WorkingTreeIterator.filterClean(WorkingTreeIterator.java:470) ... 22 more OpenJDK replaces the underlying OutputStream with NullOutputStream when the process exits. This throws IOException for all write operation. When it exits before JGit writes the input to the pipe buffer, the input stays in BufferedOutputStream. The close method tries to write it again, and IOException is thrown. Since we ignore IOException in StreamGobbler, we also ignore it when we close the stream. Fixes Bug 499633. Change-Id: I30c7ac78e05b00bd0152f697848f4d17d53efd17 Signed-off-by: Masaya Suzuki --- org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index 253acbb76..ec587d599 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -990,7 +990,16 @@ public int runProcess(ProcessBuilder processBuilder, new StreamGobbler(inRedirect, outputStream) .call(); } - outputStream.close(); + try { + outputStream.close(); + } catch (IOException e) { + // When the process exits before consuming the input, the OutputStream + // is replaced with the null output stream. This null output stream + // throws IOException for all write calls. When StreamGobbler fails to + // flush the buffer because of this, this close call tries to flush it + // again. This causes another IOException. Since we ignore the + // IOException in StreamGobbler, we also ignore the exception here. + } return process.waitFor(); } catch (IOException e) { ioException = e;