Bug 410052 - [implementation] ConcurrentModificationException while switching between editors
Summary: [implementation] ConcurrentModificationException while switching between editors
Status: ASSIGNED
Alias: None
Product: Eclemma
Classification: Technology
Component: General (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 normal
Target Milestone: ---   Edit
Assignee: Project inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 449013 453105 467073 (view as bug list)
Depends on:
Blocks:
 
Reported: 2013-06-06 06:05 EDT by Rüdiger Herrmann CLA
Modified: 2019-03-22 12:26 EDT (History)
4 users (show)

See Also:


Attachments
Eclemma clearing its annotations on a coverage launch start. (304.61 KB, image/png)
2019-03-06 06:08 EST, Simeon Andreev CLA
no flags Details
Outline view iterating over annotations while Eclemma is clearing them. (322.77 KB, image/png)
2019-03-06 06:17 EST, Simeon Andreev CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rüdiger Herrmann CLA 2013-06-06 06:05:55 EDT
While switching between (Java source) editors, I sporadically get a ConcurrentModificationException exception logged. As you can see in the stack trace, in this case the source to open was selected from the call hierarchy.

Stack trace:
java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
	at java.util.AbstractList$Itr.next(Unknown Source)
	at org.eclipse.jface.text.source.AnnotationModel$MetaIterator.hasNext(AnnotationModel.java:224)
	at org.eclipse.jface.text.source.AnnotationModel$MetaIterator.hasNext(AnnotationModel.java:228)
	at org.eclipse.jface.text.source.AnnotationModel$MetaIterator.hasNext(AnnotationModel.java:228)
	at org.eclipse.jdt.ui.ProblemsLabelDecorator.getErrorTicksFromAnnotationModel(ProblemsLabelDecorator.java:379)
	at org.eclipse.jdt.ui.ProblemsLabelDecorator.computeAdornmentFlags(ProblemsLabelDecorator.java:232)
	at org.eclipse.jdt.ui.ProblemsLabelDecorator.decorateImage(ProblemsLabelDecorator.java:170)
	at org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider.decorateImage(JavaUILabelProvider.java:134)
	at org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider.getImage(JavaUILabelProvider.java:149)
	at org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.getImage(DelegatingStyledCellLabelProvider.java:184)
	at org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider.getImage(DecoratingStyledCellLabelProvider.java:167)
	at org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.update(DelegatingStyledCellLabelProvider.java:118)
	at org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider.update(DecoratingStyledCellLabelProvider.java:134)
	at org.eclipse.jface.viewers.ViewerColumn.refresh(ViewerColumn.java:152)
	at org.eclipse.jface.viewers.AbstractTreeViewer.doUpdateItem(AbstractTreeViewer.java:953)
	at org.eclipse.jface.viewers.AbstractTreeViewer$UpdateItemSafeRunnable.run(AbstractTreeViewer.java:113)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:49)
	at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
	at org.eclipse.jface.viewers.AbstractTreeViewer.doUpdateItem(AbstractTreeViewer.java:1033)
	at org.eclipse.jface.viewers.StructuredViewer$UpdateItemSafeRunnable.run(StructuredViewer.java:485)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:49)
	at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
	at org.eclipse.jface.viewers.StructuredViewer.updateItem(StructuredViewer.java:2167)
	at org.eclipse.jface.viewers.AbstractTreeViewer.createTreeItem(AbstractTreeViewer.java:848)
	at org.eclipse.jface.viewers.AbstractTreeViewer$1.run(AbstractTreeViewer.java:823)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
	at org.eclipse.jface.viewers.AbstractTreeViewer.createChildren(AbstractTreeViewer.java:797)
	at org.eclipse.jface.viewers.TreeViewer.createChildren(TreeViewer.java:644)
	at org.eclipse.jface.viewers.AbstractTreeViewer.createChildren(AbstractTreeViewer.java:768)
	at org.eclipse.jface.viewers.AbstractTreeViewer.internalInitializeTree(AbstractTreeViewer.java:1548)
	at org.eclipse.jface.viewers.TreeViewer.internalInitializeTree(TreeViewer.java:833)
	at org.eclipse.jface.viewers.AbstractTreeViewer$5.run(AbstractTreeViewer.java:1532)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1443)
	at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:403)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1404)
	at org.eclipse.jface.viewers.AbstractTreeViewer.inputChanged(AbstractTreeViewer.java:1525)
	at org.eclipse.jface.viewers.ContentViewer.setInput(ContentViewer.java:280)
	at org.eclipse.jface.viewers.StructuredViewer.setInput(StructuredViewer.java:1690)
	at org.eclipse.jdt.internal.ui.javaeditor.JavaOutlinePage.createControl(JavaOutlinePage.java:1038)
	at org.eclipse.ui.views.contentoutline.ContentOutline.doCreatePage(ContentOutline.java:137)
	at org.eclipse.ui.part.PageBookView.createPage(PageBookView.java:408)
	at org.eclipse.ui.part.PageBookView.partActivated(PageBookView.java:751)
	at org.eclipse.ui.views.contentoutline.ContentOutline.partBroughtToTop(ContentOutline.java:212)
	at org.eclipse.ui.part.PageBookView$4.partBroughtToTop(PageBookView.java:1018)
	at org.eclipse.ui.internal.PartListenerList2$2.run(PartListenerList2.java:85)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.runtime.Platform.run(Platform.java:857)
	at org.eclipse.ui.internal.PartListenerList2.fireEvent(PartListenerList2.java:55)
	at org.eclipse.ui.internal.PartListenerList2.firePartBroughtToTop(PartListenerList2.java:83)
	at org.eclipse.ui.internal.PartService.firePartBroughtToTop(PartService.java:212)
	at org.eclipse.ui.internal.WorkbenchPagePartList.firePartBroughtToTop(WorkbenchPagePartList.java:76)
	at org.eclipse.ui.internal.WorkbenchPagePartList.fireActiveEditorChanged(WorkbenchPagePartList.java:52)
	at org.eclipse.ui.internal.PartList.setActiveEditor(PartList.java:162)
	at org.eclipse.ui.internal.WorkbenchPage.makeActiveEditor(WorkbenchPage.java:1359)
	at org.eclipse.ui.internal.WorkbenchPage.setActivePart(WorkbenchPage.java:3633)
	at org.eclipse.ui.internal.WorkbenchPage.internalActivate(WorkbenchPage.java:691)
	at org.eclipse.ui.internal.WorkbenchPage.activate(WorkbenchPage.java:663)
	at org.eclipse.ui.internal.WorkbenchPage.busyOpenEditorBatched(WorkbenchPage.java:2961)
	at org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor(WorkbenchPage.java:2854)
	at org.eclipse.ui.internal.WorkbenchPage.access$11(WorkbenchPage.java:2846)
	at org.eclipse.ui.internal.WorkbenchPage$10.run(WorkbenchPage.java:2797)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
	at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:2793)
	at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:2777)
	at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:2768)
	at org.eclipse.jdt.internal.ui.javaeditor.EditorUtility.openInEditor(EditorUtility.java:373)
	at org.eclipse.jdt.internal.ui.javaeditor.EditorUtility.openInEditor(EditorUtility.java:179)
	at org.eclipse.jdt.ui.JavaUI.openInEditor(JavaUI.java:698)
	at org.eclipse.jdt.internal.ui.callhierarchy.CallHierarchyUI.openInEditor(CallHierarchyUI.java:168)
	at org.eclipse.jdt.internal.ui.callhierarchy.CallHierarchyViewPart$CallHierarchyOpenEditorHelper.open(CallHierarchyViewPart.java:181)
	at org.eclipse.ui.OpenAndLinkWithEditorHelper$InternalListener.open(OpenAndLinkWithEditorHelper.java:48)
	at org.eclipse.jface.viewers.StructuredViewer$2.run(StructuredViewer.java:866)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:49)
	at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
	at org.eclipse.jface.viewers.StructuredViewer.fireOpen(StructuredViewer.java:864)
	at org.eclipse.jface.viewers.StructuredViewer.handleOpen(StructuredViewer.java:1152)
	at org.eclipse.jface.viewers.StructuredViewer$6.handleOpen(StructuredViewer.java:1256)
	at org.eclipse.jface.util.OpenStrategy.fireOpenEvent(OpenStrategy.java:275)
	at org.eclipse.jface.util.OpenStrategy.access$2(OpenStrategy.java:269)
	at org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrategy.java:309)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4169)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3758)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
Comment 1 Dani Megert CLA 2013-06-06 07:10:38 EDT
(In reply to comment #0)
> While switching between (Java source) editors, I sporadically get a
> ConcurrentModificationException exception logged. As you can see in the
> stack trace, in this case the source to open was selected from the call
> hierarchy.

Does it only happen when opening editors or also when manually switching editors? I assume you can't reproduce it? What's the build id?
Comment 2 Rüdiger Herrmann CLA 2013-06-06 08:32:28 EDT
(In reply to comment #1)
> [ ... ]
> Does it only happen when opening editors or also when manually switching
> editors? I assume you can't reproduce it? What's the build id?
I'm afraid, I can't reproduce it. IIRC, the editor to show the file from the call hierarchy was already open but not the active one.
The build id is I20120608-1200 (changed the version accordingly), however I couldn't find a ConcurrentModificationException bug with a target milstone of 3.8.1, 3.8.2, or 3.8.2+
Comment 3 Marcel Bruch CLA 2014-11-24 14:26:14 EST
*** Bug 453105 has been marked as a duplicate of this bug. ***
Comment 4 Marcel Bruch CLA 2014-11-24 14:26:20 EST
*** Bug 449013 has been marked as a duplicate of this bug. ***
Comment 5 Dani Megert CLA 2015-05-12 04:26:23 EDT
*** Bug 467073 has been marked as a duplicate of this bug. ***
Comment 6 Simeon Andreev CLA 2019-03-06 04:47:09 EST
In my Eclipse installation, I see 3 implementations of retrieving an iterator of an annotation model:

1. org.eclipse.jface.text.source.AnnotationModel.getAnnotationIterator()
2. org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer.getAnnotationIterator()
3. org.eclipse.eclemma.internal.ui.annotation.CoverageAnnotationModel.getAnnotationIterator()

The first two look fine, they copy the underlying data structures before returning an iterator over the copy. I'm double checking them though.


The Eclemma annotation iterator is simply an array iterator, no copies:

https://github.com/eclipse/eclemma/blob/master/org.eclipse.eclemma.ui/src/org/eclipse/eclemma/internal/ui/annotation/CoverageAnnotationModel.java

  /** List of current CoverageAnnotation objects */
  private List<CoverageAnnotation> annotations = new ArrayList<CoverageAnnotation>(
      32);

  ...

  public Iterator getAnnotationIterator() {
    return annotations.iterator();
  }

In our R&D, we received a report about the same ConcurrentModificationException while running JUnit tests with Eclemma coverage.

I'm not sure whether the Eclemma model can actually land in the same code as in the ConcurrentModificationException stack trace, so far I only see org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider$CompilationUnitAnnotationModel on the stack.
Comment 7 Dani Megert CLA 2019-03-06 05:58:13 EST
(In reply to Simeon Andreev from comment #6)
> The first two look fine, they copy the underlying data structures before
> returning an iterator over the copy. I'm double checking them though.
> 
> 
> The Eclemma annotation iterator is simply an array iterator, no copies:
This would explain why we could never reproduce it.
Comment 8 Simeon Andreev CLA 2019-03-06 06:08:37 EST
Created attachment 277777 [details]
Eclemma clearing its annotations on a coverage launch start.
Comment 9 Simeon Andreev CLA 2019-03-06 06:17:18 EST
Created attachment 277780 [details]
Outline view iterating over annotations while Eclemma is clearing them.

I believe I had to enable the following preference to run into the problem:

Window -> Preferences -> General -> Appearance -> Label Decorations -> enable Java Code Coverage decoration

I also had the JUnit view and the Outline view open.

I see a thread stack at .clear() of the same array which is about to be iterated over by org.eclipse.jdt.ui.ProblemsLabelDecorator.getErrorTicksFromAnnotationModel(IAnnotationModel, ISourceReference).

The compilation unit model has attachments (field AnnotationModel.fAttachments), one of the attachments is the coverage model. I believe for this I had to enable the Java Code Coverage decoration, but I'm not 100% sure. Our R&D IDE does not have the preference set per default and most developers are content with our default preferences.

The other annotation iterators I see (mentioned in comment 6) seem thread-safe, though I guess any annotation iterator implementation which isn't thread-safe can cause the problem.

So should we move this to Eclemma? Code which iterates over annotations (e.g. ProblemsLabelDecorator.getErrorTicksFromAnnotationModel) probably shouldn't handle concurrency problems of annotation models.
Comment 10 Eclipse Genie CLA 2019-03-06 13:54:49 EST
New Gerrit change created: https://git.eclipse.org/r/138169