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

Poorly documented SwingWorker#doInBackground() with regards to exceptions policy

XMLWordPrintable

      A DESCRIPTION OF THE REQUEST :
      If method doInBackground() throws an exception, this exception is lost unless the programmer does SwingWorker#get(). According to the SwingWorker documentation, the doInBackground() method throws an exception if it is unable to compute the result. However it doesn't say that this exception is lost unless the programmer does worker.get().

      In some cases, the program does not need to do worker.get() to obtain the result, as the swing worker may update some shared variables inside doInBackground(). Inside done() no indications are shown about the state of the worker, as this is reported as DONE.

      This behaviour (i.e. not re-throwing the exception unless you do get()), is a feature of FutureTask, see also not-bug 6373621. This behaviour also occurs with SwingWorker because SwingWorker uses a FutureTask, but this is nowhere documented.

        See also:
      http://forums.sun.com/thread.jspa?messageID=10384030#10384030

      JUSTIFICATION :
      Exceptions may get lost due to improper use of the SwingWorker. However this "improper" usage is not documented and programmers may have a hard time figuring out the source of the error.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I am not sure whether doInBackground() should re-throw the exception or not, as a question raised as to which thread will catch this new exception. It should be documented in javadoc so that programmers cater for exceptions thrown in doInBackground().

      ---------- BEGIN SOURCE ----------
      package testing;

      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;

      import javax.swing.JButton;
      import javax.swing.JFrame;
      import javax.swing.SwingWorker;

      public class TestFutures {

      public static void main(String[] args) {

      JFrame frame = new JFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      JButton button = new JButton("Invoke");
      frame.getContentPane().add(button);
      frame.pack();
      frame.setVisible(true);
      button.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
      CommunicationWorker worker = new CommunicationWorker();
      worker.execute();//
      //Only if I do the next call I get the exception
      //worker.get();
      }
      });
      }


      private static class CommunicationWorker extends SwingWorker<Void, Void>{
                      //guaranteed exception to be thrown that is lost unless I do get
      protected Void doInBackground() {
      if(true)
      throw new RuntimeException();

      return null;
      }

      }// CommunicationWorker class


      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Thanks to: http://forums.sun.com/thread.jspa?messageID=10384030#10387189
      protected void done() {
                          try {
                               get(); //ignore return value, just check correctness of completion
                          } catch (InterruptedException e) {
                              //Who will interrupt EDT? But, in any case, let Swing/AWT handle this
                              Thread.currentThread().interrupt();
                          } catch (ExecutionException e) {
                              e.getCause().printStackTrace();
                          }
      }

            peterz Peter Zhelezniakov
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: