JDK-4823180 : JDK 1.4.1: Race conditions in Motif java.awt.Choice
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris_8
  • CPU: sparc
  • Submitted: 2003-02-24
  • Updated: 2005-11-24
  • Resolved: 2003-03-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2_12Fixed
Description
Name: rmT116609			Date: 02/24/2003


FULL PRODUCT VERSION :
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)


FULL OPERATING SYSTEM VERSION :
SunOS titan 5.8 Generic_108528-18 sun4u sparc SUNW,Ultra-60

A DESCRIPTION OF THE PROBLEM :
Choice.select(int sel) seems to post an event to the event
queue which then calls select again.  If items have been
removed from the Choice in the meantime, an
IllegalArgumentException occurs.

java.lang.IllegalArgumentException: illegal Choice item
position: 3
	at java.awt.Choice.select(Choice.java:426)
	at sun.awt.motif.MChoicePeer$1.run(MChoicePeer.java:105)
	at
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
	at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:197)
	at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
	at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144)
	at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136)
	at
java.awt.EventDispatchThread.run(EventDispatchThread.java:99)



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.In event handler, select(3) on the choice
2.Then in the same handler, remove all but two items from
the choiuce
3.Observe the exception.

This is illustrated in the source code; just compile and run
on a Motif system.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalArgumentException: illegal Choice item position: 3
	at java.awt.Choice.select(Choice.java:426)
	at sun.awt.motif.MChoicePeer$1.run(MChoicePeer.java:105)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
	at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:197)
	at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:99)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;

public class ctest extends Frame implements ActionListener

  { private Choice choice;
    
    public static void main(String [] args)
      { new ctest(); }

    ctest()
      { choice = new Choice();
	choice.add("   ");
	    
	for (int i = 1; i <= 5; i ++)
	  choice.add("Initial item " + i);

	add(BorderLayout.NORTH, choice);
	    
	Button b = new Button("Adjust");
	add(BorderLayout.SOUTH, b);
	b.addActionListener(this);

	pack(); show();
      }

    public void actionPerformed(ActionEvent e)
      { choice.select(3);
	
	for (int i = choice.getItemCount()-1; i >= 1; i --)
	  choice.remove(i);

	choice.add("Revised item 1");
	choice.select(1);
      }
  }

---------- END SOURCE ----------
(Review ID: 181620) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger FIXED IN: tiger INTEGRATED IN: tiger
14-06-2004

EVALUATION Name: ssR10077 Date: 02/26/2003 ###@###.### 2003-02-26 The MChoicePeer.action tries to select on EventDispatchThread. It's impractical to sync Toolkit with EDT. But we can sync run method to prevent Exceptions and make selection and ItemEvent consistent. ======================================================================
11-06-2004

SUGGESTED FIX Name: ssR10077 Date: 02/26/2003 ------- MChoicePeer.java ------- *** /tmp/dDWayKZ Wed Feb 26 13:41:13 2003 --- MChoicePeer.java Wed Feb 26 13:48:23 2003 *************** *** 82,91 **** } } ! void notifySelection(int index) { Choice c = (Choice)target; ItemEvent e = new ItemEvent(c, ItemEvent.ITEM_STATE_CHANGED, ! c.getItem(index), ItemEvent.SELECTED); postEvent(e); } --- 82,91 ---- } } ! void notifySelection(String item) { Choice c = (Choice)target; ItemEvent e = new ItemEvent(c, ItemEvent.ITEM_STATE_CHANGED, ! item, ItemEvent.SELECTED); postEvent(e); } *************** *** 97,110 **** inUpCall = false; /* Used to prevent native selection. */ MToolkit.executeOnEventHandlerThread(c, new Runnable() { public void run() { ! if (c.getItemCount() == 0) { ! /* Nothing to do when the list is empty. */ ! return; ! } ! inUpCall = true; /* Prevent native selection. */ ! c.select(index); /* set value in target */ ! notifySelection(index); ! inUpCall = false; } }); } --- 97,114 ---- inUpCall = false; /* Used to prevent native selection. */ MToolkit.executeOnEventHandlerThread(c, new Runnable() { public void run() { ! String item; ! synchronized(c) { ! if (index >= c.getItemCount()) { ! /* Nothing to do when the list is too short. */ ! return; ! } ! inUpCall = true; /* Prevent native selection. */ ! c.select(index); /* set value in target */ ! item = c.getItem(index); ! inUpCall = false; ! } ! notifySelection(item); } }); } ###@###.### 2003-02-26 ======================================================================
26-02-2003