This discussion is archived
6 Replies Latest reply: Sep 26, 2013 9:47 PM by 963782 RSS

When the Worker.State FAILED occurs in a Task?

963782 Newbie
Currently Being Moderated

How to detect that a Worker.State FAILED occurs in a Task? or to say when the Worker.State FAILED occurs in a Task? Is it when an exception happens in the call() method of Task?

 

Consider the code below:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import javafx.concurrent.Task;
/**
 * Background task to fetch the all classes documentation page from a URL
 */
public class FetchDocListTask extends Task<String> {
  private final String docsDirUrl;
  public FetchDocListTask(String docsDirUrl) {
  this.docsDirUrl = docsDirUrl;
  }
  @Override
  protected String call() throws Exception {
  System.out.println("---- FetchDocListTask  docsUrl = " + docsDirUrl);
  StringBuilder builder = new StringBuilder();
  try {
  URI uri = new URI(docsDirUrl + "allclasses-frame.html");
  URL url = uri.toURL();
  URLConnection urlConnection = url.openConnection();
  urlConnection.setConnectTimeout(5000); // set timeout to 5 secs
  InputStream in = urlConnection.getInputStream();
  BufferedReader reader = new BufferedReader(
  new InputStreamReader(in));
  String line;
  while ((line = reader.readLine()) != null) {
  builder.append(line);
  builder.append('\n');
  }
  reader.close();
  } catch (URISyntaxException e) {
  e.printStackTrace();
  }
  return builder.toString();
  }
}

When the State.FAILED occurs? In fact, I want to write a code to simply detect whether the computer is connected to the internet. Hope for help~

  • 1. Re: When the Worker.State FAILED occurs in a Task?
    shakir.gusaroff Expert
    Currently Being Moderated

    1.You can override the task’s failed method.

     

    @Override protected void failed() {
                 super.failed();
                //----------------
             }
    

     

    There is an example of ‘Reacting To State Changes Generically’ at

    http://docs.oracle.com/javafx/2/api/javafx/concurrent/Task.html

     

    2. You can also use task's stateproperty:

     

    task.stateProperty().addListener(new ChangeListener<State>() {
                public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
                    if (newValue == State.FAILED) {
                   
                    }
                }
            });
        }

    3. You can also use onFailed even handler:

      task.setOnFailed(EventHandler<WorkerStateEvent> value) {}

  • 2. Re: When the Worker.State FAILED occurs in a Task?
    963782 Newbie
    Currently Being Moderated

    Thanks for your reply, I learnt a lot. However, I want to know what will cause the state to be FAILED in my posted example. And if I want to write a code to simply detect whether the computer is connected to the internet, how to modify the codes?

  • 3. Re: When the Worker.State FAILED occurs in a Task?
    James_D Guru
    Currently Being Moderated

    A task moves to a FAILED state when the call(...) method exits due to an unhandled exception. In the method for handling the change to the FAILED state, you can call task.getException() to get details about what happened.

     

    As well as the mechanisms for handling changes to the FAILED state that Shakir mentioned, you can also set the onFailed property on the task:

     

    final Task<String> fetchDocTask = new FetchDocListTask(...);
    fetchDocTask.setOnFailed(new EventHandler<WorkerStateEvent>() {
         @Override
         public void handle(WorkerStateEvent event) {
              Exception exception = fetchDocTask.getException();
              // ...
         }
    });

     

    I find using a setOnFailed(...), along with a setOnSucceeded(...) and sometimes a setOnCancelled(...) cleaner than registering a listener on the state and having a switch or collection of if/else clauses to handle the different states.

  • 4. Re: When the Worker.State FAILED occurs in a Task?
    963782 Newbie
    Currently Being Moderated

    Thanks, James_D. You mentioned: A task moves to a FAILED state when the call(...) method exits due to an unhandled exception. Is it to say when the exception which occurs in the call() method is handled, the task does not transit to FAILED state?

  • 5. Re: When the Worker.State FAILED occurs in a Task?
    James_D Guru
    Currently Being Moderated

    Yes. If the call() method exits due to an unhandled exception, the state property changes to FAILED. If a return statement is successfully executed, the state property changes to SUCCEEDED. There are no other possibilities.

     

    You can test with something like:

     

    import javafx.application.Application;
        import javafx.concurrent.Task;
        import javafx.concurrent.WorkerStateEvent;
        import javafx.event.EventHandler;
        import javafx.scene.Scene;
        import javafx.scene.control.TextArea;
        import javafx.scene.layout.BorderPane;
        import javafx.stage.Stage;
        
        
        public class TaskStateTest extends Application {
            public static void main(String[] args) { launch(args); }
            @Override
            public void start(final Stage primaryStage) {
                Task<Void> exceptionHandlingTask = new Task<Void>() {
            
                    @Override
                    protected Void call() throws Exception {
                        try {
                            throw new Exception("Boom");
                        } catch (Exception exc) {
                            System.out.println(exc.getMessage() + " handled");
                        }
                        return null;
                    }
                    
                };
                
                Task<Void> exceptionThrowingTask = new Task<Void>() {
            
                    @Override
                    protected Void call() throws Exception {
                        throw new Exception("Boom");
            //            return null;
                    }
                    
                };
                
                final BorderPane root = new BorderPane();
                final TextArea textArea = new TextArea();
                root.setCenter(textArea);
                
                primaryStage.setScene(new Scene(root, 600, 400));
                primaryStage.show();
                
                registerHandlers(exceptionHandlingTask, "exceptionHandlingTask", textArea);
                registerHandlers(exceptionThrowingTask, "exceptionThrowingTask", textArea);
                
                Thread t1 = new Thread(exceptionHandlingTask);
                Thread t2 = new Thread(exceptionThrowingTask);
                t1.start();
                t2.start();
            }
            private void registerHandlers(final Task<Void> task, final String msg, final TextArea textArea) {
                task.setOnFailed(new EventHandler<WorkerStateEvent>() {
        
                    @Override
                    public void handle(WorkerStateEvent event) {
                        textArea.appendText(msg + " failed\n");
                    }
                    
                });
                task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
        
                    @Override
                    public void handle(WorkerStateEvent event) {
                        textArea.appendText(msg +  " succeeded\n");
                    }
                    
                });
            }
        }
  • 6. Re: When the Worker.State FAILED occurs in a Task?
    963782 Newbie
    Currently Being Moderated

    Thank you much, it is now very clear to me~

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points