0

I'd like to close connections when exiting the swing application. So as suggested here: Running a method when closing the program?

I added following code, in the main to the main thread, ending up with following stack trace. It does perform my closeConnections method.

/** 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
Community
  • 1
  • 1
Finn
  • 1
  • 3
  • Try get the LoggerContext state and test on it before shuting it down: (LoggerContext)LogManager.getContext().getState() – jMounir May 05 '15 at 12:01
  • @jMounir getState() method doesn't exist the way you suggest. It's log4j2 – Finn May 05 '15 at 13:51
  • Sorry I was mistaken, its should be called like this: ((LoggerContext)LogManager.getContext()).getState() – jMounir May 05 '15 at 14:11
  • @jMounir I've added it at the top of the run method. I get State = started. The error as shown in the original post is shown before the "state = started" printout. – Finn May 05 '15 at 17:30
  • Where have put this code. cause i see the comment `/** on exit */` do you mean the on exit event ?. because you cannot register a shutdown hook when the program is performin a shutdown. here what is said in the documentation: _Once the shutdown sequence has begun it is impossible to register a new shutdown hook or de-register a previously-registered hook. Attempting either of these operations will cause an IllegalStateException to be thrown._ from http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html – jMounir May 06 '15 at 08:32
  • @jMounir I've put the code directly in the main thread. The /** onexit**/ is to indicate that this happens on exit. – Finn May 06 '15 at 19:17

1 Answers1

0

I think the log4j also has a shutdown hook and the order of the execution of shutdwon hook decided by the JVM, so you can not influence it. I might be possible to disable log4j shutdownhook and do the cleanup yourself, but it might be better to check what log4j does.

HamoriZ
  • 2,370
  • 18
  • 38