stop()
will only be called if you exit the application via Platform.exit()
(or when the last window is closed if Platform.implicitExit
is true). Shutdown hooks will execute if System.exit()
is called, or if the native process running the JVM is interrupted (e.g. ctrl-C on a *nix-like OS), in addition to the usual way of exiting a JavaFX Application.
Note that it appears to be important to register the shutdown hook in the main thread, before calling Application.launch()
.
stop()
is executed on the FX Application Thread, so it is safe to access UI elements (e.g. to show "save unsaved changes" dialogs, etc). Shutdown hooks are run in a background thread, so cannot access UI elements (indeed the FX Toolkit will probably long have stopped running by that stage).
So the choice depends on the use case.
To make this a little more concrete, here's a quick test class:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ShutdownTest extends Application {
@Override
public void start(Stage primaryStage) {
Button platformExit = new Button("Platform Exit");
platformExit.setOnAction(e -> Platform.exit());
Button systemExit = new Button("System Exit");
systemExit.setOnAction(e -> System.exit(0));
Button hang = new Button("Hang");
hang.setOnAction(e -> {while(true);});
HBox root = new HBox(5, platformExit, systemExit, hang);
root.setPadding(new Insets(20));
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
@Override
public void stop() {
System.out.println("Stop");
}
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Shutdown hook")));
launch(args);
}
}
I tested this on Mac OS X.
Exiting via the "Platform Exit" button, by closing the window, or by right-clicking on the Dock and choosing "Quit" will execute both the stop()
method and the shutdown hook.
Exiting by the "System Exit" button, by forcing the process to quit from "Activity Monitor", or by killing the process by kill id
from the command line, will execute the shutdown hook only. Hanging the application by pressing the "Hang" button and then right-clicking on the Dock and choosing "Force Quit" has the same result.
Exiting by sending a SIGKILL to the process (kill -9 id
or kill -SIGKILL id
from the command line) executes neither the stop()
method nor the shutdown hook.