Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX 2 - Catching all runtime exceptions

I tried

Thread.setDefaultUncaughtExceptionHandler...


in the main, and also in the start(Stage primaryStage) method. It ain't working.
I also tried

public static void main(String[] args) {
 try {
  launch(args);
 }catch(Throwable t) {
  System.out.println(t.getMessage);
 }
}


Exception stack trace.

at javafx.concurrent.Task$TaskCallable$2.run(Task.java:1251) at com.sun.javafx.application.PlatformImpl$3.run(PlatformImpl.java:141) at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) at com.sun.glass.ui.gtk.GtkApplication$1$1.run(GtkApplication.java:56) at java.lang.Thread.run(Thread.java:662)

Thanks for helping.

like image 425
jerome Avatar asked Sep 07 '12 13:09

jerome


People also ask

Can runtime exceptions be caught?

Runtime exceptions represent problems that are a direct result of a programming problem, and as such shouldn't be caught since it can't be reasonably expected to recover from them or handle them. Catching Throwable will catch everything. This includes all errors, which aren't actually meant to be caught in any way.

Can you catch all exceptions Java?

Java allows you to catch multiple type exceptions in a single catch block. It was introduced in Java 7 and helps to optimize code. You can use vertical bar (|) to separate multiple exceptions in catch block. An old, prior to Java 7 approach to handle multiple exceptions.

Are all exceptions thrown at runtime?

All the exceptions occur at runtime. On the other hand, UnchekedExceptions[aka RuntimeExcetions] are less likely to occur and the programmer is not forced to handle those while writing the program.

Why we should not catch runtime exception?

Having to add runtime exceptions in every method declaration would reduce a program's clarity. Thus, the compiler does not require that you catch or specify runtime exceptions (although you can). One case where it is common practice to throw a RuntimeException is when the user calls a method incorrectly.


2 Answers

If you check the code for Platform.runLater() (see below), you will see that the exceptions are swallowed (lines 146 / 147), so a default uncaught exception handler won't be able to catch them - based on that piece of code, I don't think you have any options but to include try/catch blocks in your runnables.

Note that this issue has been reported (requires login - registration is free) and should be fixed in Lombard (= Java FX 8.0 to be released with Java 8 next year).

You could alternatively create a utility method and call

Platform.runLater(getFxWrapper(yourRunnable));

public static Runnable getFxWrapper(final Runnable r) {
    return new Runnable() {

        @Override
        public void run() {
            try {
                r.run();
            } catch (Exception e) {
                //here you probably want to log something
                System.out.println("Found an exception");
            }
        }
    };
}

Code of Platform.runLater:

  120     private static void runLater(final Runnable r, boolean exiting) {
  121         if (!initialized.get()) {
  122             throw new IllegalStateException("Toolkit not initialized");
  123         }
  124 
  125         pendingRunnables.incrementAndGet();
  126         waitForStart();
  127 
  128         if (SystemProperties.isDebug()) {
  129             Toolkit.getToolkit().pauseCurrentThread();
  130         }
  131 
  132         synchronized (runLaterLock) {
  133             if (!exiting && toolkitExit.get()) {
  134                 // Don't schedule a runnable after we have exited the toolkit
  135                 pendingRunnables.decrementAndGet();
  136                 return;
  137             }
  138 
  139             Toolkit.getToolkit().defer(new Runnable() {
  140                 @Override public void run() {
  141                     try {
  142                         r.run();
  143                         pendingRunnables.decrementAndGet();
  144                         checkIdle();
  145                     } catch (Throwable t) {
  146                         System.err.println("Exception in runnable");
  147                         t.printStackTrace();
  148                     }
  149                 }
  150             });
  151         }
  152     }
like image 147
assylias Avatar answered Oct 01 '22 13:10

assylias


Some managed threads such as the UI Event Handler and ExecutorServices capture Throwable themselves to avoid the threads dying. Only threads which die will use this UncaughtExceptionHandler. If you want to capture exception thrown you have to do thsi in the method which can throw these exceptions.

If the UI Event Handler has a way of reporting exceptions it will be a different method.

Your second example will catch exception thrown in that thread. Exception thrown on other threads will be catch on that thread.

like image 29
Peter Lawrey Avatar answered Oct 01 '22 14:10

Peter Lawrey