United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6432565 ClassCastException in SwingWorker
JDK-6432565 : ClassCastException in SwingWorker

Details
Type:
Bug
Submit Date:
2006-05-31
Status:
Resolved
Updated Date:
2010-04-02
Project Name:
JDK
Resolved Date:
2006-07-19
Component:
client-libs
OS:
linux
Sub-Component:
javax.swing
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports

Sub Tasks

Description
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().

                                    

Comments
EVALUATION

Description suggests 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.

There is a third one semi-solution - do better guessing of V. The
problem is no matter how good guessing is it is going to be guessing
only and there will be cases when the guess going to be wrong.

For the SwingWorker.process method there are no advantages of using V[] versus List<V> as an argument.
I am going to change signature of this method to 
protected void process(List<V> chunks)
                                     
2006-06-06



Hardware and Software, Engineered to Work Together