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

ClassCastException in SwingWorker

XMLWordPrintable

    • b92
    • x86
    • linux

      FULL PRODUCT VERSION :
      java version "1.6.0-beta2"
      Java(TM) SE Runtime Environment (build 1.6.0-beta2-b85)
      Java HotSpot(TM) Client VM (build 1.6.0-beta2-b85, mixed mode, sharing)


      ADDITIONAL OS VERSION INFORMATION :
      Linux localhost.localdomain 2.6.15-1.1833_FC4 #1 Wed Mar 1 23:41:37 EST 2006 i686 i686 i386 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      The EDT (Event dispatch Thread) raises a ClassCastException
      with the code below.

      Data published by doInBackground() are stored in a list
      and then converted in an array and send to method process()
      in order to reduce synchronization time between EDT and worker thread.

      The problem is to determine the class of the array passed to the process()
      method at runtime. Because generics are erased, the class of V is not
      available. The current implementation use the class of the array passed
      as argument of the first call of the method publish() . This is clearly wrong.

      Two solutions :
        - don't use an array in the signature of process() but use a List instead
        - take the class of V in the constructor.
          public SwingWorker(Class<T> tClass) {...}
            
      Note : i had reviewed the SwingWorker code when it was integrated to
      mustang (i think a year ago), it troubles me because
      it mix runtime type and generics but i was not able to produce a test case
      that show my insight until today.
      So the test case is not issue from a real application.

      Rémi Forax

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      run the code

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      it should work
      ACTUAL -
      it throws a ClassCastException

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "AWT-EventQueue-0" java.lang.ArrayStoreException
      at java.lang.System.arraycopy(Native Method)
      at java.util.ArrayList.toArray(ArrayList.java:306)
      at sun.swing.AccumulativeRunnable.flush(AccumulativeRunnable.java:148)
      at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:96)
      at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:598)
      at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.swing.SwingWorker;

      public class SwingWorkerTest {
          public static void main(String[] args) {
            new SwingWorker<Void,CharSequence>() {
              @Override
              protected Void doInBackground() {
                publish(new String[] {"hello"});
                publish(new StringBuilder("world"));
                return null;
              }
            }.execute();
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Add this line
      publish(new CharSequence[0]);
      as the first line of doInBackground().

            idk Igor Kushnirskiy (Inactive)
            rmandalasunw Ranjith Mandala (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: