Issue
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.
Solution
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.
Answered By - alaptiko
Answer Checked By - Willingham (JavaFixing Volunteer)