1

I have a JavaFX application that at some time needs to run separate processes (updater executable) and terminate. I'm running a separate process by using ProcessBuilder.command() and watching when sub process will become !isAlive() which means the process ran completely. After this I am trying to terminate the application by running Window.getWindows().forEach(::dispose) and then System.exit(0).

After calling System.exit(0) the application hangs, but if there is no separate process to run the application terminates correctly.

Here is part of the main thread stacktrace:

"JavaFX Application Thread" #32 prio=5 os_prio=0 tid=0x000000001f4fe000 nid=0x44d0 in Object.wait() [0x0000000023f4d000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Thread.join(Thread.java:1252)

  • locked <0x00000006c21ac608> (a java.lang.Thread) at java.lang.Thread.join(Thread.java:1326) at java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:106) at java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:46) at java.lang.Shutdown.runHooks(Shutdown.java:123) at java.lang.Shutdown.sequence(Shutdown.java:167) at java.lang.Shutdown.exit(Shutdown.java:212)
  • locked <0x00000006c2148fb8> (a java.lang.Class for java.lang.Shutdown) at java.lang.Runtime.exit(Runtime.java:109) at java.lang.System.exit(System.java:971)

So it seems the application waits for some ApplicationShutdownHooks to complete. There were two hooks added in the application, but after removing them, stacktrace stays the same.

What hooks could be added implicitly? Maybe the separate processes should be run in different ways to be able to close before the sub process will be closed?

UPD: This application is actually not a full JavaFX application, but an AWT application with a JavaFX part.

2 Answers 2

2

Your application still is waiting for all shutdown hooks to be completed, I expect there still is some hook.

The runHooks methods is automatically ran when the application exits. And the application will exit when it completes (it also does some other cleanup besides this). See the code below:

static void runHooks() {
    Collection<Thread> threads;
    synchronized(ApplicationShutdownHooks.class) {
        threads = hooks.keySet();
        hooks = null;
    }

    for (Thread hook : threads) {
        hook.start();
    }
    for (Thread hook : threads) {
        try {
            hook.join();
        } catch (InterruptedException x) { }
    }
}

Each hook is a Thread that has not been started. Shutting down starts all threads (hook.start()) and then waits for them all to complete/die (hook.join()).

You stacktrace shows there is a shutdownhook Thread that does not complete. Here is how to find out which.

The Thread.join() method is synchronized on this and the 'locked' line tells you which Thread object is the problem:

    at java.lang.Thread.join(Thread.java:1252)
    - locked <0x00000006c21ac608> (a java.lang.Thread)
    at java.lang.Thread.join(Thread.java:1326)

This number is a unique number for the object (I think the virtual memory adress). This number should be in the full threaddump for the application, or if not, you can use a debugger to find the object in the set with all shutdown hooks (java.lang.ApplicationShutdownHooks#hooks).

After this you can look at this thread to see what it is waiting for.

Note that it is possible that some library you use adds shutdownhooks, not just your own hooks.

Sign up to request clarification or add additional context in comments.

Comments

1

The problem was in the application structure. It was actually a Swing/AWT application with JavaFX components launched manually. So when Platform.exit() or Systen.exit(0) was called, the AWT windows stayed alive and prevented the application from complete termination. In this case there was a requirement to dispose the active AWT window properly and then call Platform.exit():

 window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 window.dispose();
 Platform.exit()

and then call Platform.exit() to close the JavaFX part of the application.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.