Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 413048

Summary: [Commands] ConcurrentModificationException in command manager during addExecutionListener
Product: [Eclipse Project] Platform Reporter: Jörg Mann <joerg.mann>
Component: UIAssignee: Platform UI Triaged <platform-ui-triaged>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: christoph.pohl, michael.muehlberg
Version: 4.3Keywords: helpwanted
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard: stalebug

Description Jörg Mann CLA 2013-07-16 05:45:18 EDT
Code snippet:

1) myListener = new MyListener();
2) ICommandService commandService = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
3) commandService.addExecutionListener(myListener);

Line 3) sometimes bails out with 

java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
	at java.util.HashMap$ValueIterator.next(HashMap.java:822)
	at org.eclipse.core.commands.CommandManager.addExecutionListener(CommandManager.java:324)
	at org.eclipse.ui.internal.commands.CommandService.addExecutionListener(CommandService.java:110)
	at ...

It seems to be at random and depending on timing issues. The critical section is in CommandManager, method addExecutionListener where an iterator is used. We found bug 88629 which seems to solve a similar problem by using an array (copy) rather than an iterator.

Thanks
Jörg
Comment 1 Paul Webster CLA 2013-07-22 14:10:18 EDT
I can have a look at this, but the ICommandService is designed to be used on the UI thread and looking at the iterator loop in question, Command.addExecutionListener(*) doesn't fire out to any code that could update the list of commands in the iterator loop.

How is this being added?

PW
Comment 2 Jörg Mann CLA 2013-07-23 02:27:13 EDT
Hi PW

the call happens during early startup inside an UIJob, but maybe someone else is calling the API in parallel in a non ui thread.

We currently use a workaround which seems to work so far


---snip---
try {
  // first try
  commandService.addExecutionListener(refreshCommandListener);

} catch (ConcurrentModificationException e) {
  IStatus status = .... // a warning for error log

  // second try usually succeeds
  commandService.addExecutionListener(refreshCommandListener);
}
---snip---

Thanks
Jörg
Comment 3 Paul Webster CLA 2013-07-23 13:58:17 EDT
OK, the array pattern can be used here as well.  If someone provides a fix I'll consider it for Kepler SR1 or SR2.

PW
Comment 4 Lars Vogel CLA 2019-11-27 07:02:45 EST
This bug hasn't had any activity in quite some time. Maybe the problem got
resolved, was a duplicate of something else, or became less pressing for some
reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it.
The information can be, for example, that the problem still occurs, that you
still want the feature, that more information is needed, or that the bug is
(for whatever reason) no longer relevant.

If the bug is still relevant, please remove the stalebug whiteboard tag.