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

Opening an https connection from a javafx.concurrent.Task prevents Task thread from closing

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      runtime: JDK 15
      OS: Windows 10
      JavaFX: org.openjfx.javafx-base, version 11.0.2

      A DESCRIPTION OF THE PROBLEM :
      When using javafx.concurrent.Task, opening a connection to a URL prevents the Task thread from closing, even, when the stream is then closed.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      When the Task includes 2 lines opening a stream and closing it, the Task returns correctly. Its `succeed` method runs. **But the Service' `setOnSucceeded` method does not run.** Why?

      When the 2 lines about the streaming opening and closing are commented out in the Task, we do get the expected behavior: `System.out.println("in the succeed method of the Service")` does print.

      The Main method:

          package Test;
          
          import javafx.application.Application;
          import javafx.concurrent.Worker;
          import javafx.stage.Stage;
          
          public class Main extends Application {
          
              public static void main(String[] args) {
                  launch(args);
              }
          
              @Override
              public void start(Stage primaryStage) {
          
                  MyService pluginUpdateService = new MyService();
                  pluginUpdateService.setOnFailed(e -> {
                      System.out.println("task failed");
                  });
                  pluginUpdateService.setOnSucceeded(e -> {
                      System.out.println("in the succeed method of the Service"); // this does not print, when MyTask opens the stream (see code of MyTask)
                  });
                  // launching the service
                  if (pluginUpdateService.getState() == Worker.State.READY) {
                      pluginUpdateService.start();
                  }
              }
          }

      The service `MyService`

          package Test;
          
          import javafx.concurrent.Service;
          import javafx.concurrent.Task;
          
          public class MyService extends Service {
          
              public MyService() {
              }
          
              @Override
              protected Task createTask() {
                  Task updater = new MyTask();
                  return updater;
              }
          }
      The task `MyTask`:
          
          package Test;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.net.MalformedURLException;
          import java.net.URL;
          import javafx.concurrent.Task;
          
          
          public class MyTask extends Task {
          
          
              public MyTask() {
          
              }
          
              @Override
              protected Void call() throws MalformedURLException, IOException {
                  InputStream in;
                      URL url = new URL("https://clementlevallois.net");
                      in = url.openStream(); // when this line is commented out, the Service does trigger its setOnSucceeded method as expected
                      in.close(); // when this line is commented out, the Service does trigger its setOnSucceeded method as expected
                  System.out.println("about to return from the call method of the Task");
                  return null;
              }
          
              @Override
              protected void succeeded() {
                  super.succeeded();
                  System.out.println("succeeded - sent from the succeeded method of the Task");
              }
          
              @Override
              protected void cancelled() {
                  super.cancelled();
                  System.out.println("cancelled");
                  updateMessage("Cancelled!");
              }
          
              @Override
              protected void failed() {
                  super.failed();
                  System.out.println("failed");
                  updateMessage("Failed!");
              }
          
          }

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The setOnSucceed method of the service should be called
      ACTUAL -
      The setOnSucceed method of the service is not called.

      ---------- BEGIN SOURCE ----------
      When the Task includes 2 lines opening a stream and closing it, the Task returns correctly. Its `succeed` method runs. **But the Service' `setOnSucceeded` method does not run.** Why?

      When the 2 lines about the streaming opening and closing are commented out in the Task, we do get the expected behavior: `System.out.println("in the succeed method of the Service")` does print.

      The Main method:

          package Test;
          
          import javafx.application.Application;
          import javafx.concurrent.Worker;
          import javafx.stage.Stage;
          
          public class Main extends Application {
          
              public static void main(String[] args) {
                  launch(args);
              }
          
              @Override
              public void start(Stage primaryStage) {
          
                  MyService pluginUpdateService = new MyService();
                  pluginUpdateService.setOnFailed(e -> {
                      System.out.println("task failed");
                  });
                  pluginUpdateService.setOnSucceeded(e -> {
                      System.out.println("in the succeed method of the Service"); // this does not print, when MyTask opens the stream (see code of MyTask)
                  });
                  // launching the service
                  if (pluginUpdateService.getState() == Worker.State.READY) {
                      pluginUpdateService.start();
                  }
              }
          }

      The service `MyService`

          package Test;
          
          import javafx.concurrent.Service;
          import javafx.concurrent.Task;
          
          public class MyService extends Service {
          
              public MyService() {
              }
          
              @Override
              protected Task createTask() {
                  Task updater = new MyTask();
                  return updater;
              }
          }
      The task `MyTask`:
          
          package Test;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.net.MalformedURLException;
          import java.net.URL;
          import javafx.concurrent.Task;
          
          
          public class MyTask extends Task {
          
          
              public MyTask() {
          
              }
          
              @Override
              protected Void call() throws MalformedURLException, IOException {
                  InputStream in;
                      URL url = new URL("https://clementlevallois.net");
                      in = url.openStream(); // when this line is commented out, the Service does trigger its setOnSucceeded method as expected
                      in.close(); // when this line is commented out, the Service does trigger its setOnSucceeded method as expected
                  System.out.println("about to return from the call method of the Task");
                  return null;
              }
          
              @Override
              protected void succeeded() {
                  super.succeeded();
                  System.out.println("succeeded - sent from the succeeded method of the Task");
              }
          
              @Override
              protected void cancelled() {
                  super.cancelled();
                  System.out.println("cancelled");
                  updateMessage("Cancelled!");
              }
          
              @Override
              protected void failed() {
                  super.failed();
                  System.out.println("failed");
                  updateMessage("Failed!");
              }
          
          }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      none found. See https://stackoverflow.com/questions/66707119/task-succeeds-but-the-service-onsucceed-method-is-not-triggered

      FREQUENCY : always


            kcr Kevin Rushforth
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: