Skip to content

Extensive performance issues with Lombok and STS/Eclipse #1717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
chris922 opened this issue Jun 5, 2018 · 8 comments
Open

Extensive performance issues with Lombok and STS/Eclipse #1717

chris922 opened this issue Jun 5, 2018 · 8 comments

Comments

@chris922
Copy link

chris922 commented Jun 5, 2018

In our team we've got extensive performance issues using lombok in STS for one of our projects. We've got several smaller projects (more or less libraries) where we are using lombok and one really big project (Java EE application) where we don't use lombok up to now. The performance issues only exists in this big project where we don't use lombok. It looks like the code assist is really slow, but we even tried to disable it and typing is still very slow. STS hangs after typing a few letters for a few seconds. This makes it nearly impossible for us to continue development.

As a workaround we will open the big project in a separate STS instance without the Lombok agent.

We are using different STS versions in our team, I know that some colleagues have 3.8.x, I have 3.9.4.
My version 3.9.4 is based on Eclipse Neon.3 (4.6.3).
I tried it with the lombok version 1.18.0 that was released today. Java version 1.8.0u111.

This is the list of detected "hot spots" using YourKit profiler:

Method Time (ms) Count
lombok.eclipse.TransformEclipseAST.go() TransformEclipseAST.java 296228 73434
lombok.eclipse.EclipseAST.traverse(EclipseASTVisitor) EclipseAST.java 293914 886921
lombok.eclipse.EclipseNode.traverse(EclipseASTVisitor) EclipseNode.java 293450 187654840
lombok.eclipse.EclipseAST.traverseChildren(EclipseASTVisitor, EclipseNode) EclipseAST.java 292765 163095753
lombok.eclipse.HandlerLibrary.callASTVisitors(EclipseAST, long, boolean) HandlerLibrary.java 65913 807774
lombok.core.LombokConfiguration.read(ConfigurationKey, AST) LombokConfiguration.java 49628 517373
lombok.eclipse.handlers.HandleFieldDefaults.visitType(EclipseNode, TypeDeclaration) HandleFieldDefaults.java 48166 256081
lombok.core.configuration.FileSystemSourceCache$2$1.findNext() FileSystemSourceCache.java 44351 517373
lombok.core.configuration.FileSystemSourceCache.getSourceForDirectory(File, ConfigurationProblemReporter) FileSystemSourceCache.java 40623 6561202
lombok.eclipse.HandlerLibrary.handleAnnotation(CompilationUnitDeclaration, EclipseNode, Annotation, long) HandlerLibrary.java 32855 21966496
lombok.core.configuration.FileSystemSourceCache.ensureContent(File) FileSystemSourceCache.java 32280 6561202
java.util.concurrent.ConcurrentHashMap.get(Object) ConcurrentHashMap.java 30550 7199183
lombok.eclipse.TransformEclipseAST$AnnotationVisitor.visitAnnotationOnField(FieldDeclaration, EclipseNode, Annotation) TransformEclipseAST.java 28671 15968634

I also attached an export about all method invocations:

lombok_performance-issue-with-sts.xlsx

If you like I can also provide the YourKit dump or let me know what I should trace. Unfortunately the project is closed source and thus I can't provide you a link so that you can try it yourself.

Maybe this issue is related to #749.

Anyway: Thanks for thousands of lines of boilerplate we don't needed to write! We are really looking forward to be able to use Lombok in all our projects.

@chris922
Copy link
Author

Is someone working on this issue or do you need more information? Just let me know if I can support you somehow!

I tried it today again with Lombok 1.18.2 and I still have the same performance issue. I even tried to add Lombok to the project and also defined one @Data class. So also using Lombok in the project will not solve the performance issues. We still need a separate STS instance for this project and can't use Lombok there 😢

@liptga
Copy link

liptga commented Oct 5, 2018

In our project we have Lombok in use. One colleague had extreme performance problems. After typeing 2 characters, we had to wait several seconds. After taking several threaddumps, I realized how to fix his computer.

1. Disable Lombok Configuration

There is a configuration possibility, which I have seen in LombokConfiguration. If you do not have a lombok.config file, then you can disable eclipse from searching of it. Just define -Dlombok.disableConfig=true as JVM argument, and its gone. Eclipse will not look for the config on every key press.

One recommendation could be for the lombok developer: it would be good to cache all lombok.config files in the memory. Then you would just need to subscribe somehow to get notified about new lombok.config files or about updates to them. This way the config would not be searched on every key press.

2. Close the Help View

We kept on seeing such things in Stacktrace:

java.lang.Thread.State: RUNNABLE
at java.util.regex.Pattern$Start.match(Pattern.java:3419)
at java.util.regex.Matcher.search(Matcher.java:1211)
at java.util.regex.Matcher.find(Matcher.java:604)
at java.util.regex.Pattern.split(Pattern.java:1212)
at java.util.regex.Pattern.split(Pattern.java:1271)
at java.lang.String.split(String.java:1757)
at lombok.eclipse.agent.PatchVal.couldBe(PatchVal.java:88)
at lombok.eclipse.agent.PatchVal.is(PatchVal.java:109)
at lombok.eclipse.agent.PatchVal.isVar(PatchVal.java:215)
at lombok.eclipse.agent.PatchVal.handleValForLocalDeclaration(PatchVal.java:149)
at sun.reflect.GeneratedMethodAccessor66.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:56)
at java.lang.reflect.Method.invoke(Method.java:620)
at lombok.launch.PatchFixesHider$Util.invokeMethod(PatchFixesHider.java:115)
at lombok.launch.PatchFixesHider$Val.handleValForLocalDeclaration(PatchFixesHider.java:256)
at org.eclipse.jdt.internal.compiler.ast.LocalDeclaration.resolve(LocalDeclaration.java)
at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolveStatements(AbstractMethodDeclaration.java:641)
at org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.resolveStatements(MethodDeclaration.java:309)
at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolve(AbstractMethodDeclaration.java:551)
at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.resolve(TypeDeclaration.java:1188)
at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.resolve(TypeDeclaration.java:1301)
at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.resolve(CompilationUnitDeclaration.java:590)
at org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:861)
at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:883)
at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:588)
at org.eclipse.jdt.core.dom.ASTParser.createASTs(ASTParser.java:899)
at org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv.createASTs(BaseProcessorEnv.java:857)
at org.eclipse.jdt.apt.core.internal.env.ReconcileEnv.openPipeline(ReconcileEnv.java:108)
at org.eclipse.jdt.apt.core.internal.env.AbstractCompilationEnv.newReconcileEnv(AbstractCompilationEnv.java:97)
at org.eclipse.jdt.apt.core.internal.APTDispatchRunnable.reconcile(APTDispatchRunnable.java:219)
at org.eclipse.jdt.apt.core.internal.APTDispatchRunnable.runAPTDuringReconcile(APTDispatchRunnable.java:167)
at org.eclipse.jdt.apt.core.internal.AptCompilationParticipant.reconcile(AptCompilationParticipant.java:213)
at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation$1.run(ReconcileWorkingCopyOperation.java:258)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.notifyParticipants(ReconcileWorkingCopyOperation.java:245)
at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.executeOperation(ReconcileWorkingCopyOperation.java:95)
at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:729)
at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:789)
at org.eclipse.jdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1250)
at org.eclipse.jdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1211)
at org.eclipse.jdt.internal.corext.util.JavaModelUtil.reconcile(JavaModelUtil.java:609)
at org.eclipse.jdt.internal.ui.actions.SelectionConverter.codeResolve(SelectionConverter.java:271)
at org.eclipse.jdt.internal.ui.actions.SelectionConverter.codeResolve(SelectionConverter.java:151)
at org.eclipse.jdt.internal.ui.actions.SelectionConverter.codeResolve(SelectionConverter.java:136)
at org.eclipse.jdt.internal.ui.actions.SelectionConverter.getStructuredSelection(SelectionConverter.java:75)
at org.eclipse.jdt.internal.ui.util.JavaUIHelp.getHelpContextProvider(JavaUIHelp.java:60)
at org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.getAdapter(JavaEditor.java:2279)
at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor.getAdapter(CompilationUnitEditor.java:1776)
at org.eclipse.help.ui.internal.views.HelpView.updateActivePart(HelpView.java:198)
at org.eclipse.help.ui.internal.views.HelpView.access$0(HelpView.java:187)
at org.eclipse.help.ui.internal.views.HelpView$1.run(HelpView.java:334)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
- locked (a org.eclipse.swt.widgets.RunnableLock)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4155)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3772)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1127)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:337)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1018)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:694)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:337)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:606)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:139)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:380)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:235)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:56)
at java.lang.reflect.Method.invoke(Method.java:620)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:669)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:608)
at org.eclipse.equinox.launcher.Main.run(Main.java:1515)
at org.eclipse.equinox.launcher.Main.main(Main.java:1488)

The bad part is that obviously the Help View updates its content completely in UI thread (see the stack frame at org.eclipse.help.ui.internal.views.HelpView.updateActivePart(HelpView.java:198). In case of Java Editors the content sensitive view needs a compiled java file, and this compilation takes place in UI Thread. Combined with the processing from Lombok and its uncached config file this is a fatal performance issue.

I will file a bug report to Eclipse Project to have Help View probably fixed.

After fixing both issues by my colleague eclipse became completely responsive again.

If this does not fix your case, please take stacktraces, when eclipse hangs, and attach here. This could help the investigation.

@liptga
Copy link

liptga commented Oct 5, 2018

Eclipse issue is opened: https://bugs.eclipse.org/bugs/show_bug.cgi?id=539840 . Lets see if it will be fixed :)

@kgyrtkirk
Copy link

@liptga I think the issue you were experiencing is different than from the originally reported one which seems to be related to TransformEclipseAST - but anyway; I've tried -Dlombok.disableConfig=false and it didn't worked

Right now the only workaround I know around this problem is do disable lombok completely (by removing the javaagent from eclipse.ini).

If anyone would like to look into the issue; there are some generated classes in Hive which are affected; here are the steps to use it to repro the ssue:

git clone https://github.com/apache/hive/
cd hive
mvn install -pl  standalone-metastore/metastore-common/ -DskipTests -am
mvn eclipse:eclipse -pl standalone-metastore/metastore-common/
# import metastore-common into an eclipse instance which has lombok installed

@liptga
Copy link

liptga commented Jun 3, 2019

@kgyrtkirk Zoltan, do you have the help view opened? If not, then the thing that would help is really just taking threaddumps, and attaching to this issue. Then the investigation would be surely faster. Could you please attach some threaddumps?

@kgyrtkirk
Copy link

nope, I don't have the help view opened...I never do :D
I'm not sure but I think a proper repro environment worth more than stacktrace or a threaddump...but sure here you go:
a

@liptga
Copy link

liptga commented Jun 4, 2019

Please attach a complete threaddump of a "blackout" of your eclipse. What you attached, shows only that lombok does something. The interesting part would be who calls lombok.

How to make a thread dump:
https://docs.oracle.com/javase/8/docs/technotes/guides/visualvm/applications_local.html

@Arnaud-Nauwynck
Copy link

Arnaud-Nauwynck commented Dec 2, 2019

I also encountered slowness ... and as a matter of chance, it was also after opening some hive source module in my eclipse!
Here is a stack-trace

stack-eclipse-lombok.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants