Closing the standard output streams System.out or System.err will cause all
subsequent standard output to be dropped, including stack traces from exceptions
that propagate to the top level.
Avoid using try-with-resources to manage PrintWriters or OutputStreams that
wrap System.out or System.err, since the try-with-resource statement will
close the underlying streams.
That is, prefer this:
PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.err));
pw.println("hello");
pw.flush();
Instead of this:
try (PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.err))) {
pw.println("hello");
}
Consider the following example:
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import static java.nio.charset.StandardCharsets.UTF_8;
public class X {
public static void main(String[] args) {
System.err.println("one");
try (PrintWriter err = new PrintWriter(new OutputStreamWriter(System.err, UTF_8))) {
err.print("two");
}
// System.err has been closed, no more output will be printed!
System.err.println("three");
throw new AssertionError();
}
}
The program will print the following, and return with exit code 1. Note that the
last println doesn’t produce any output, and the exception’s stack trace is
not printed:
one
two
Suppress false positives by adding the suppression annotation @SuppressWarnings("ClosingStandardOutputStreams") to the enclosing element.