Eclipse freezes due to multi thread WeakHashMap access in lombok #625

Open
lombokissues opened this Issue Jul 14, 2015 · 4 comments

Projects

None yet

1 participant

@lombokissues
Collaborator

Migrated from Google Code (issue 590)

@lombokissues
Collaborator

👤 nutin.happened   🕗 Oct 11, 2013 at 13:16 UTC

What steps will reproduce the problem?

  1. Start Eclipse with many projects with many lombok annotations.
  2. Immediately start to edit files.

What is the expected output? What do you see instead?
Eclipse should work normally. Instead Eclipse freezes.

What version of the product are you using? On what operating system?
Eclipse 4.2.2, Win 7, Eclipse running with jdk1.7.0_40 (same behavior seen with 1.6.* too)

Please provide any additional information below.
I looked up threads in jconsole. Last time Eclipse froze it had 4 threads accessing a WeakHashMap:

Name: Worker-199
Stack trace:
java.util.WeakHashMap.getEntry(WeakHashMap.java:498)
java.util.WeakHashMap.containsKey(WeakHashMap.java:485)
lombok.eclipse.handlers.EclipseHandlerUtil.findGetter(EclipseHandlerUtil.java:883)
lombok.eclipse.handlers.EclipseHandlerUtil.getFieldType(EclipseHandlerUtil.java:961)
lombok.eclipse.handlers.HandleEqualsAndHashCode.createEquals(HandleEqualsAndHashCode.java:618)
lombok.eclipse.handlers.HandleEqualsAndHashCode.generateMethods(HandleEqualsAndHashCode.java:235)
lombok.eclipse.handlers.HandleEqualsAndHashCode.handle(HandleEqualsAndHashCode.java:140)
lombok.eclipse.HandlerLibrary$AnnotationHandlerContainer.handle(HandlerLibrary.java:103)
lombok.eclipse.HandlerLibrary.handleAnnotation(HandlerLibrary.java:237)
lombok.eclipse.TransformEclipseAST$AnnotationVisitor.visitAnnotationOnType(TransformEclipseAST.java:209)
lombok.eclipse.EclipseNode.traverse(EclipseNode.java:96)
...
org.eclipse.ui.internal.decorators.LightweightDecoratorManager.decorate(LightweightDecoratorManager.java:365)
org.eclipse.ui.internal.decorators.LightweightDecoratorManager.getDecorations(LightweightDecoratorManager.java:347)
org.eclipse.ui.internal.decorators.DecorationScheduler$1.ensureResultCached(DecorationScheduler.java:371)
org.eclipse.ui.internal.decorators.DecorationScheduler$1.run(DecorationScheduler.java:331)
org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)

Name: Worker-202
Stack trace:
java.util.WeakHashMap.put(WeakHashMap.java:521)
lombok.eclipse.handlers.EclipseHandlerUtil.registerCreatedLazyGetter(EclipseHandlerUtil.java:873)
lombok.eclipse.handlers.HandleGetter.createGetter(HandleGetter.java:262)
lombok.eclipse.handlers.HandleGetter.createGetterForField(HandleGetter.java:218)
lombok.eclipse.handlers.HandleGetter.createGetterForFields(HandleGetter.java:166)
lombok.eclipse.handlers.HandleGetter.handle(HandleGetter.java:152)
lombok.eclipse.HandlerLibrary$AnnotationHandlerContainer.handle(HandlerLibrary.java:103)
lombok.eclipse.HandlerLibrary.handleAnnotation(HandlerLibrary.java:237)
lombok.eclipse.TransformEclipseAST$AnnotationVisitor.visitAnnotationOnField(TransformEclipseAST.java:189)
lombok.eclipse.EclipseNode.traverse(EclipseNode.java:99)
...
org.eclipse.jdt.ui.SharedASTProvider.getAST(SharedASTProvider.java:128)
org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$PartListenerGroup.calculateASTandInform(SelectionListenerWithASTManager.java:170)
org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$PartListenerGroup$3.run(SelectionListenerWithASTManager.java:155)

  • locked java.lang.Object@ 45aa9603
    org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)

Name: org.eclipse.jdt.internal.ui.text.JavaReconciler
Stack trace:
java.util.WeakHashMap.put(WeakHashMap.java:521)
lombok.eclipse.handlers.EclipseHandlerUtil.registerCreatedLazyGetter(EclipseHandlerUtil.java:873)
lombok.eclipse.handlers.HandleGetter.createGetter(HandleGetter.java:262)
lombok.eclipse.handlers.HandleGetter.createGetterForField(HandleGetter.java:218)
lombok.eclipse.handlers.HandleGetter.createGetterForFields(HandleGetter.java:166)
lombok.eclipse.handlers.HandleGetter.handle(HandleGetter.java:152)
lombok.eclipse.HandlerLibrary$AnnotationHandlerContainer.handle(HandlerLibrary.java:103)
lombok.eclipse.HandlerLibrary.handleAnnotation(HandlerLibrary.java:237)
lombok.eclipse.TransformEclipseAST$AnnotationVisitor.visitAnnotationOnField(TransformEclipseAST.java:189)
lombok.eclipse.EclipseNode.traverse(EclipseNode.java:99)
...
org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:87)
org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:151)
org.eclipse.jdt.internal.ui.text.CompositeReconcilingStrategy.reconcile(CompositeReconcilingStrategy.java:86)
org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.reconcile(JavaCompositeReconcilingStrategy.java:104)
org.eclipse.jface.text.reconciler.MonoReconciler.process(MonoReconciler.java:77)
org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run(AbstractReconciler.java:206)

Name: ModalContext
Stack trace:
java.util.WeakHashMap.put(WeakHashMap.java:521)
lombok.eclipse.handlers.EclipseHandlerUtil.registerCreatedLazyGetter(EclipseHandlerUtil.java:873)
lombok.eclipse.handlers.HandleGetter.createGetter(HandleGetter.java:262)
lombok.eclipse.handlers.HandleGetter.createGetterForField(HandleGetter.java:218)
lombok.eclipse.handlers.HandleGetter.createGetterForFields(HandleGetter.java:166)
lombok.eclipse.handlers.HandleGetter.handle(HandleGetter.java:152)
lombok.eclipse.HandlerLibrary$AnnotationHandlerContainer.handle(HandlerLibrary.java:103)
lombok.eclipse.HandlerLibrary.handleAnnotation(HandlerLibrary.java:237)
lombok.eclipse.TransformEclipseAST$AnnotationVisitor.visitAnnotationOnField(TransformEclipseAST.java:189)
lombok.eclipse.EclipseNode.traverse(EclipseNode.java:99)
...
org.eclipse.jdt.internal.core.Openable.codeSelect(Openable.java:162)
org.eclipse.jdt.internal.core.CompilationUnit.codeSelect(CompilationUnit.java:377)
org.eclipse.jdt.internal.core.CompilationUnit.codeSelect(CompilationUnit.java:371)
org.eclipse.jdt.internal.ui.actions.SelectionConverter.codeResolve(SelectionConverter.java:273)
org.eclipse.jdt.internal.ui.actions.SelectionConverter$1CodeResolveRunnable.run(SelectionConverter.java:257)
org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)

Cause:
WeakHashMap is not thread safe.

Solution:
change line 868 in EclipseHandlerUtil from:
private static final Map<FieldDeclaration, Object> generatedLazyGettersWithPrimitiveBoolean = new WeakHashMap<FieldDeclaration, Object>();
to:
private static final Map<FieldDeclaration, Object> generatedLazyGettersWithPrimitiveBoolean = Collections.synchronizedMap(new WeakHashMap<FieldDeclaration, Object>());

@lombokissues
Collaborator

👤 r.spilker   🕗 Mar 11, 2014 at 19:26 UTC

Hmm, we've overlooked this issue. Working on it right now. We're not just solving this problem, but also other similar potential problems.

@lombokissues
Collaborator

👤 r.spilker   🕗 Mar 17, 2014 at 21:34 UTC

Pushed an implementation to master.

@lombokissues
Collaborator

End of migration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment