Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8124412

Platform.runLater() prevents Application.stop() from being called if given a Runnable that throws and Exception.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • P4
    • None
    • 7u15
    • javafx

    Description

      Edit: Sorry, I can't seem to get the formatting right for the code blocks.

      The following application will exit fine if you start it and close the window immediately. However, if you click the 'Click Me' button first, the Application.stop() method will never be called.

      {code}
      public class TestExitApplication extends Application {
          @Override
          public void start(Stage primaryStage) throws Exception {
              try {
                  Scene scene = new Scene(createButton());
                  primaryStage.setScene(scene);
                  primaryStage.setTitle("Echo Client");
                  primaryStage.show();
              } catch (Exception e) {
                  System.out.println("Exiting due to startup failure.");
                  System.exit(1);
              }
          }

          @Override
          public void stop() throws Exception {
              System.out.println("Exiting via call to stop().");
              System.exit(0);
          }

          private Button createButton() {
              Button button = new Button("Click Me!");
              button.setOnAction(new EventHandler<ActionEvent>() {
                  @Override
                  public void handle(ActionEvent actionEvent) {
                      Platform.runLater(new Runnable() {
                          @Override
                          public void run() {
                              throw new RuntimeException("Oh no!");
                          }
                      });
                  }
              });
              return button;
          }

          public static void main(String[] args) {
              System.out.println(VersionInfo.getRuntimeVersion());
              Application.launch(TestExitApplication.class);
          }
      }
      {code}

      The {{PlatformImpl}} class has this block of code:

      {code}
      Toolkit.getToolkit().defer(new Runnable() {
          @Override public void run() {
              try {
                  r.run();
                  pendingRunnables.decrementAndGet();
                  checkIdle();
              } catch (Throwable t) {
                  System.err.println("Exception in runnable");
                  t.printStackTrace();
              }
          }
      });
      {code}

      Shouldn't the decrement of pendingRunnables happen in a finally block? Once a Runnable has failed with an exception, it's not longer pending, right?

      Also, is Platform.runLater() supposed to be swallowing exceptions like that?

      Attachments

        Issue Links

          Activity

            People

              kcr Kevin Rushforth
              rjjfx Ryan J (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported: