System.setErr() interferes with Logger

后端 未结 1 1117
日久生厌
日久生厌 2021-01-28 04:50

In a larger program, I am using a static java.util.logging.Logger instance, but redirecting System.err to several different files in succession. The

相关标签:
1条回答
  • 2021-01-28 05:33

    By default the JRE is configured to load a ConsoleHandler on the root logger. Your log message will travel up to the root logger handlers by default. The root logger handlers are loaded on demand. In your current program, the lazy loading of the root logger ConsoleHandler is capturing your 1st redirected System.err. After that, the root logger handler is never reloaded which is why you'll never see the log message in log 2. Plus the 1st redirected stream is closed so now the root ConsoleHandler is writing to a closed stream.

    To prove this point, add the following as the first lines of your test case main method and run the program.

    Logger.getLogger("").getHandlers(); //Force load root logger handlers.
    Logger.getLogger("").removeHandler((Handler) null);
    

    You'll see that now no logger messages are recorded. If you are curious why this works you can read the java.util.logging.LogManager$RootLogger source code for details.

    What you need to do is create a StreamHandler with your redirected System.err stream and then add and remove the StreamHandler from your logger. You can also toggle the use of parent handlers on your logger config to avoid writing to the original System.err.

    Another possible solution would be to find all ConsoleHandler instances. Remove and close all of them. Perform the remap System.err. Then create and attach new ConsoleHandlers.

    JDK wise, the ConsoleHandler and ErrorManager should have been designed to use the java.io.FileDescriptor which is never redirected.

    0 讨论(0)
提交回复
热议问题