5

I'm currently trying to build an application with JavaFX 8, but I can't get uncaught exception handling to work. Due to this post (https://bugs.openjdk.java.net/browse/JDK-8100937) it should be fixed / implemented with JavaFX 8 (Lombard), but I can't find anything on the net...

I don't want to go the hackish way, may you give me a hint where to search for further information?

beat
  • 1,857
  • 1
  • 22
  • 36
bash0r
  • 774
  • 6
  • 17
  • can you give an example (code) of what you are doing that causes the issue? – SnakeDoc May 12 '14 at 15:26
  • It's not a particular code that causes trouble, I just have no point to look for further information about the newly implemented exception handling. The global exception handling is meant to catch unhandled exceptions, print a short sorry message to the user and to exit afterwards. – bash0r May 12 '14 at 15:28

2 Answers2

13

As I understand it, there's nothing much to it; you just use the regular uncaught exception handling from java.lang.Thread.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class UncaughtExceptionTest extends Application {

    @Override
    public void start(Stage primaryStage) {

        // start is called on the FX Application Thread, 
        // so Thread.currentThread() is the FX application thread:
        Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> {
            System.out.println("Handler caught exception: "+throwable.getMessage());
        });

        StackPane root = new StackPane();
        Button button = new Button("Throw exception");
        button.setOnAction(event -> {
            throw new RuntimeException("Boom!") ;
        });
        root.getChildren().add(button);
        Scene scene = new Scene(root, 150, 60);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
James_D
  • 201,275
  • 16
  • 291
  • 322
  • Isn't there more than one thread to worry about here though? ex. JavaFX application thread? I would think you'd need to do this a second time with Platform.runLater(). – User Aug 23 '16 at 19:02
  • Ok, right, that's handled - what about other threads? Does calling Thread.setUncaughtExceptionHandler (static method instead) catch everything? Javadoc doesn't seem to make that clear. – User Aug 23 '16 at 19:38
  • [Docs](http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setDefaultUncaughtExceptionHandler-java.lang.Thread.UncaughtExceptionHandler-) seem pretty clear to me. *If* the thread itself has no uncaught exception handler set, and *if* the thread group to which it belongs doesn't override the uncaughtException method, *then* the handler set in `Thread.setDefaultUncaughtExceptionHandler()` (if any) is invoked. – James_D Aug 23 '16 at 19:45
  • 1
    It would just be a bit clearer if they used the phrase "all" or "any" thread explicitly instead of leaving the reader to infer that with the static context. Or maybe it just seems too damn easy and I'm subconsciously skeptical... – User Aug 23 '16 at 21:31
0

James_D's answer helped me a lot, but I overlooked his comment. So in case others face the same issue, I post this as a complementary answer.

In my case, my JavaFX app had to face and catch an Out Of Memory Error. For the same code sometimes the OOM appeared on the JavaFX main thread, sometimes not (could be "InvokeLaterDispatcher" thread, "Timer" thread, "process reaper" thread, ...), depending on which thread was first running out of memory. Consequently the error was not always caught and the app didn't always exit as required.

Thus to be sure my app was logging this and exiting, I had to use Thread.setDefaultUncaughtExceptionHandler() as mentioned also by James_D in his comment:

Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
    System.out.println(throwable.getClass() + " detected from default UEH.\nWill exit now");
    System.exit(1);            
});

Now the error is always caught when it appears.

0009laH
  • 1,960
  • 13
  • 27
HelloWorld
  • 2,275
  • 18
  • 29