Reputation: 28312
Usually when I see ConcurrentModificationException
, it is due to iterating over a list and deleting something. In my case, I simply have a reference to the list and am trying to delete something from it. Here is my code:
getList(Client.class).remove(client);
This throws a ConcurrentModificationException
. classToListMap
is a declared like so
private Map<Class, ObservableList> classToListMap;
And here is the getList() function:
public <T> List<T> getList(Class T) {
return classToListMap.get(T);
}
Any ideas on why this could be throwing the exception?
Here is the full function that throws the exception:
private synchronized void deleteClient() {
DefaultMutableTreeNode node = getRightClickedNode();
if (node.getUserObject() instanceof Client == false) {
JOptionPane.showMessageDialog(null, "Please select a client to delete");
return;
}
TreeSelectionListener[] listeners = getTreeSelectionListeners();
for(TreeSelectionListener listener : listeners){
removeTreeSelectionListener(listener);
}
((DefaultTreeModel)getModel()).removeNodeFromParent(node);
Client client = (Client) node.getUserObject();
applicationContext.getDataRepository().getList(Client.class).remove(client); //!!!!!!<-- Throws exception
applicationContext.fireUpdate(new UpdateEvent(UpdateEvent.Type.DELETE, client, new UnknownEvent(this)));
for(TreeSelectionListener listener : listeners){
addTreeSelectionListener(listener);
}
}
Here is the complete stack trace:
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.remove(AbstractList.java:380)
at java.util.AbstractCollection.remove(AbstractCollection.java:293)
at com.dvsd.profmetric.ui.gui.client.gui.ClientTree.deleteClient(ClientTree.java:147)
at com.dvsd.profmetric.ui.gui.client.gui.ClientTree.access$300(ClientTree.java:39)
at com.dvsd.profmetric.ui.gui.client.gui.ClientTree$3.actionPerformed(ClientTree.java:121)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
at java.awt.Component.processMouseEvent(Component.java:6527)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6292)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4883)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4705)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
at java.awt.Container.dispatchEventImpl(Container.java:2278)
at java.awt.Window.dispatchEventImpl(Window.java:2739)
at java.awt.Component.dispatchEvent(Component.java:4705)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:719)
at java.awt.EventQueue$4.run(EventQueue.java:717)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
classToListMap
is being filled like so:
private void createClassToListMap() {
classToListMap = new LinkedHashMap<Class, ObservableList>();
classToListMap.put(ManagementProfessional.class, managementProfessionalList);
classToListMap.put(AdministrativeProfessional.class, administrativeProfessionalList);
...
And the ObservableLists
are org.jdesktop.observablecollections.ObservableList;
being created like:
List<ProfitMargin> profitMargins = simulation.getProfitMarginList();
profitMarginList = ObservableCollections.observableList(profitMargins);
Where ObservableCollections
is a org.jdesktop.observablecollections.ObservableCollections;
Upvotes: 1
Views: 145
Reputation: 269827
You haven't provided complete information, but I'm guessing that the Observable
part of ObservableList
means that changes in list content are reported to an observer, and that observer might be iterating over the list or trying to make its own modifications in the callback that is fired when you remove the element. Post a complete stack trace and information about the list observer callback if you need more help.
Upvotes: 3