Skip to content

Commit e203fa6

Browse files
authored
NullPointerException: "Deflater has been closed" emanating from FilterServletOutputStream (#553)
1 parent c83d511 commit e203fa6

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

core/src/main/java/org/kohsuke/stapler/compression/FilterServletOutputStream.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ public class FilterServletOutputStream extends ServletOutputStream {
1515
private final OutputStream out;
1616
private final ServletOutputStream realSream;
1717

18+
/**
19+
* Whether the stream is closed; implicitly initialized to false.
20+
*/
21+
private volatile boolean closed;
22+
23+
/**
24+
* Object used to prevent a race on the 'closed' instance variable.
25+
*/
26+
private final Object closeLock = new Object();
27+
1828
/**
1929
* Constructs a new {@link FilterOutputStream}.
2030
* @param out the stream that sits above the realStream, performing some filtering. This must be eventually delegating eventual writes to {@code realStream}.
@@ -42,7 +52,36 @@ public void write(byte[] b, int off, int len) throws IOException {
4252

4353
@Override
4454
public void close() throws IOException {
45-
out.close();
55+
if (closed) {
56+
return;
57+
}
58+
synchronized (closeLock) {
59+
if (closed) {
60+
return;
61+
}
62+
closed = true;
63+
}
64+
65+
Throwable flushException = null;
66+
try {
67+
flush();
68+
} catch (Throwable e) {
69+
flushException = e;
70+
throw e;
71+
} finally {
72+
if (flushException == null) {
73+
out.close();
74+
} else {
75+
try {
76+
out.close();
77+
} catch (Throwable closeException) {
78+
if (flushException != closeException) {
79+
closeException.addSuppressed(flushException);
80+
}
81+
throw closeException;
82+
}
83+
}
84+
}
4685
}
4786

4887
@Override

0 commit comments

Comments
 (0)