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
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.