问题
I want the Java ConsoleHandler
to use System.out
instead of err
, so I implemented my own handler that calls the protected void setOutputStream(OutputStream)
of the parent StreamHandler
class:
public class ConsoleHandler extends java.util.logging.ConsoleHandler {
public ConsoleHandler() {
setOutputStream(System.out); // or System.err
setLevel(Level.ALL);
}
}
I remove the default console logger from and add my own to the root logger:
Logger l = Logger.getLogger("");
for (Handler h : l.getHandlers())
l.removeHandler(h);
l.addHandler(new ConsoleHandler());
System.out.println("OUT");
System.err.println("ERR");
Problem: "OUT" is always printed, but "ERR" never, independent of the output stream I set in my ConsoleHandler constructor.
回答1:
The stacktrace (printed to System.err) is not printed any more, without my changes it is printed as usual
This is because setOutputStream
closes the previously assigned System.err stream. This is a known issue filed under JDK-4827381: Invoking ConsoleHandler.setOutputStream(...) closes System.err. What should have happened with that bug report is that the StreamHandler.setOutputStream should call Handler.close
instead of flushAndClose()
.
You need to wrap the existing System.err
stream with a proxy that doesn't allow the stream to be closed. Or just extend StreamHandler
and use the constructor that takes an OutputStream.
public class OutConsoleHandler extends StreamHandler {
public OutConsoleHandler() {
super(System.out, new SimpleFormatter());
//TODO: Read level,filter,encoding from LogManager.
}
@Override
public void publish(LogRecord record) {
super.publish(record);
super.flush();
}
@Override
public void close() {
super.flush();
}
}
来源:https://stackoverflow.com/questions/51641805/using-consolehandler-with-own-printstream-suppresses-system-err