Again, looking at the source, the solution seems to be defining the system property java.util.logging.manager , which is a subclass of LogManager that overrides the reset(); method reset(); so that the registrars continue to work at shutdown.
import java.util.logging.LogManager; import java.util.logging.Logger; public class Main { static { // must be called before any Logger method is used. System.setProperty("java.util.logging.manager", MyLogManager.class.getName()); } public static class MyLogManager extends LogManager { static MyLogManager instance; public MyLogManager() { instance = this; } @Override public void reset() { /* don't reset yet. */ } private void reset0() { super.reset(); } public static void resetFinally() { instance.reset0(); } } public static void main(String... args) { Logger logger1 = Logger.getLogger("Main1"); logger1.info("Before shutdown"); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { @Override public void run() { try { Logger logger2 = Logger.getLogger("Main2"); logger2.info("Shutting down 2"); } finally { MyLogManager.resetFinally(); } } })); } }
prints
Dec 11, 2012 5:56:55 PM Main main INFO: Before shutdown Dec 11, 2012 5:56:55 PM Main$1 run INFO: Shutting down 2
From this code for LogManager, you can see that there is a disconnect hook that parses the handlers and closes them. Logger only works when shutting down, if it has not been used before, so this code does not run.
From my own testing
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { @Override public void run() { try { Logger logger2 = Logger.getLogger("Main2"); logger2.info("Shutting down 2"); } catch (Throwable t) { t.printStackTrace(); } } }));
prints
Dec 11, 2012 5:40:15 PM Main$1 run INFO: Shutting down 2
but if you add
Logger logger1 = Logger.getLogger("Main1");
outside this block you get nothing.
source share