关闭时的java Execute方法引发log4j非法状态异常无法注册关闭
我想在退出swing应用程序时关闭连接。 正如这里所建议的:Running a method when closing the program?
我在主线程中添加了以下代码,最终得到以下堆栈跟踪。它确实执行了我的closeConnections方法
/** on exit */
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
DeviceManager.getInstance().closeConnections();
//shutdown log4j2
if( LogManager.getContext() instanceof LoggerContext ) {
LogManager.getLogger().info("Shutting down log4j2");
Configurator.shutdown((LoggerContext)LogManager.getContext());
} else{
LogManager.getLogger().warn("Unable to shutdown log4j2");}
}
}, "Shutdown-thread"));
ERROR StatusLogger catching java.lang.IllegalStateException: Shutdown in progress
at java.lang.ApplicationShutdownHooks.add(Unknown Source)
at java.lang.Runtime.addShutdownHook(Unknown Source)
at org.apache.logging.log4j.core.util.DefaultShutdownCallbackRegistry.addShutdownHook(DefaultShutdownCallbackRegistry.java:136)
at org.apache.logging.log4j.core.util.DefaultShutdownCallbackRegistry.start(DefaultShutdownCallbackRegistry.java:125)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.initializeShutdownCallbackRegistry(Log4jContextFactory.java:123)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.<init>(Log4jContextFactory.java:89)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.<init>(Log4jContextFactory.java:54)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at org.apache.logging.log4j.LogManager.<clinit>(LogManager.java:96)
at com.guitarjwindows.repositories.midi.WindowsMidiCommunicator.init(WindowsMidiCommunicator.java:46)
at com.guitarjwindows.repositories.midi.WindowsMidiCommunicator.<init>(WindowsMidiCommunicator.java:33)
at com.guitarjwindows.repositories.midi.WindowsMidiCommunicator.getInstance(WindowsMidiCommunicator.java:37)
at com.guitarjwindows.service.DeviceManager.closeConnections(DeviceManager.java:35)
at com.guitarjwindows.starter.Starter$1.run(Starter.java:33)
at java.lang.Thread.run(Unknown Source)
2015-05-05 13:30:24,505 FATAL Unable to register shutdown hook because JVM is shutting down.
[INFO ] 2015-05-05 13:30:24.515 [Shutdown-thread] WindowsMidiCommunicator - Max receivers:0
[INFO ] 2015-05-05 13:30:24.516 [Shutdown-thread] WindowsMidiCommunicator - 2- Saffire 6USBobtained as inputDevice
[INFO ] 2015-05-05 13:30:24.516 [Shutdown-thread] WindowsMidiCommunicator - Max transmitters:-1
[INFO ] 2015-05-05 13:30:24.516 [Shutdown-thread] WindowsMidiCommunicator - Open receivers:
[INFO ] 2015-05-05 13:30:24.516 [Shutdown-thread] WindowsMidiCommunicator - No default receiver
[INFO ] 2015-05-05 13:30:24.516 [Shutdown-thread] WindowsMidiCommunicator - Open transmitters:
[INFO ] 2015-05-05 13:30:24.517 [Shutdown-thread] WindowsMidiCommunicator - Default transmitter: com.sun.media.sound.MidiInDevice$MidiInTransmitter@151107e
[INFO ] 2015-05-05 13:30:24.517 [Shutdown-thread] WindowsMidiCommunicator - Open transmitters now:
[INFO ] 2015-05-05 13:30:24.517 [Shutdown-thread] WindowsMidiCommunicator - com.sun.media.sound.MidiInDevice$MidiInTransmitter@151107e
[INFO ] 2015-05-05 13:30:24.518 [Shutdown-thread] WindowsMidiCommunicator - Max receivers:-1
[INFO ] 2015-05-05 13:30:24.518 [Shutdown-thread] WindowsMidiCommunicator - 2- Saffire 6USBobtained as outputDevice
[INFO ] 2015-05-05 13:30:24.518 [Shutdown-thread] WindowsMidiCommunicator - Max transmitters:0
[INFO ] 2015-05-05 13:30:24.518 [Shutdown-thread] WindowsMidiCommunicator - Open receivers:
[INFO ] 2015-05-05 13:30:24.518 [Shutdown-thread] WindowsMidiCommunicator - Default receiver: com.sun.media.sound.MidiOutDevice$MidiOutReceiver@1716ab5
[INFO ] 2015-05-05 13:30:24.518 [Shutdown-thread] WindowsMidiCommunicator - Open receivers now:
[INFO ] 2015-05-05 13:30:24.518 [Shutdown-thread] WindowsMidiCommunicator - com.sun.media.sound.MidiOutDevice$MidiOutReceiver@1716ab5
[INFO ] 2015-05-05 13:30:24.518 [Shutdown-thread] WindowsMidiCommunicator - Open transmitters:
[ERROR] 2015-05-05 13:30:24.518 [Shutdown-thread] WindowsMidiCommunicator - No default transmitter
[INFO ] 2015-05-05 13:30:24.571 [Shutdown-thread] WindowsMidiCommunicator - outputDevice closed
[INFO ] 2015-05-05 13:30:24.572 [Shutdown-thread] WindowsMidiCommunicator - inputDevice closed
2015-05-05 13:30:24,599 FATAL Unable to register shutdown hook because JVM is shutting down.
[INFO ] 2015-05-05 13:30:24.600 [Shutdown-thread] Starter$1 - Shutting down log4j2
# 1 楼答案
我认为log4j也有一个shutdown钩子,shutdwon钩子的执行顺序由JVM决定,所以你不能影响它。我可能会禁用log4j shutdownhook并自己进行清理,但最好检查log4j的功能