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

Task throws IllegalStateException on cancel



    • Subcomponent:


      When cancelling a Task, the exception property has the value IllegalStateException, when I expect it to have a value of null:

      java.lang.IllegalStateException: Task must only be used from the FX Application Thread
      at javafx.concurrent.Task.checkThread(Task.java:1219)
      at javafx.concurrent.Task.getValue(Task.java:962)
      at javafx.concurrent.Task$TaskCallable.call(Task.java:1446)
      at java.util.concurrent.FutureTask.run(FutureTask.java:266)
      at java.lang.Thread.run(Thread.java:745)

      Actually, in an earlier version it seems like it behaved as expected: see the Fig. 6.8 on page 273, chapter "Collections and Concurrency" in Pro JavaFX 2 by James Weaver.

      Below is a runnable example that demonstrates the issue, using one of the examples in Task's api doc.

       * Created on 05.06.2013
      package chapter4layoutandcontrols;

      import javafx.application.Application;
      import javafx.application.Platform;
      import javafx.beans.binding.Bindings;
      import javafx.beans.binding.StringBinding;
      import javafx.beans.value.ChangeListener;
      import javafx.beans.value.ObservableValue;
      import javafx.concurrent.Task;
      import javafx.concurrent.Worker;
      import javafx.event.ActionEvent;
      import javafx.event.EventHandler;
      import javafx.geometry.Insets;
      import javafx.geometry.Pos;
      import javafx.scene.Parent;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.Label;
      import javafx.scene.control.TextArea;
      import javafx.scene.layout.BorderPane;
      import javafx.scene.layout.BorderPaneBuilder;
      import javafx.scene.layout.HBox;
      import javafx.scene.layout.HBoxBuilder;
      import javafx.scene.layout.Pane;
      import javafx.scene.layout.VBox;
      import javafx.stage.Stage;

       * Issue: Task throws IllegalStateException on cancel
       * To reproduce:
       * run, start, cancel - the listener to the exception property shows the message
       * "Task must only be used from the FX Application Thread" (plus
       * its stacktrace) though all access seems to be on the fx-thread.
       * @author Jeanette Winzenburg, Berlin
      @SuppressWarnings({"unchecked", "rawtypes"})
      public class WorkerIllegalStateException extends Application {

          private Task worker;

          private Button startButton;

          private Button cancelButton;

          public WorkerIllegalStateException() {
              worker = createTask();

          // This is the example from java doc of Task
          private Task createTask() {
              Task<Integer> task = new Task<Integer>() {
                  protected Integer call() throws Exception {
                      int iterations;
                      for (iterations = 0; iterations < 1000; iterations++) {
                          if (isCancelled()) {
                              updateMessage("Cancelled at " + iterations);
                          updateMessage("Iteration " + iterations);
                          updateProgress(iterations, 1000);
                          // Now block the thread for a short time, but be sure
                          // to check the interrupted exception for cancellation!
                          try {
                          } catch (InterruptedException interrupted) {
                              if (isCancelled()) {
                                  updateMessage("Cancelled at: " + iterations);
                      return iterations;
              return task;

          private void hookupEvents() {
              startButton.setOnAction(actionEvent -> new Thread(worker).start());
              cancelButton.setOnAction(actionEvent -> worker.cancel());
              // listen to changes of the exception property
              ChangeListener l = (observable, oldValue, newValue) -> {
                  if (!(newValue instanceof Throwable)) return;
                  ((Throwable) newValue).printStackTrace();

          private Parent createContent() {
              startButton = new Button("Start");
              cancelButton = new Button("Cancel");
              Label message = new Label();
              Label state = new Label();
              state.textProperty().bind(Bindings.format("%s", worker.stateProperty()));
              VBox topPane = new VBox(10);
              topPane.setPadding(new Insets(10, 10, 10, 10));
              topPane.getChildren().addAll(message, state);

              HBox buttonPane = new HBox(10);
              buttonPane.setPadding(new Insets(10, 10, 10, 10));
              buttonPane.getChildren().addAll(startButton, cancelButton);
              BorderPane pane = new BorderPane();
              return pane;

          public void start(Stage stage) throws Exception {
              Scene scene = new Scene(createContent());

          public static void main(String[] args) {


          Issue Links



              msladecek Martin Sládeček
              fastegal Jeanette Winzenburg
              0 Vote for this issue
              1 Start watching this issue