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

Bug 478754

Summary: Long refresh and build times
Product: [Eclipse Project] JDT Reporter: Benjamin Manes <ben.manes>
Component: CoreAssignee: JDT-Core-Inbox <jdt-core-inbox>
Status: CLOSED INVALID QA Contact: Stephan Herrmann <stephan.herrmann>
Severity: normal    
Priority: P3 CC: stephan.herrmann
Version: 4.5   
Target Milestone: 4.6 M3   
Hardware: PC   
OS: Mac OS X   
Whiteboard:
Attachments:
Description Flags
Generated file none

Description Benjamin Manes CLA 2015-09-30 13:57:44 EDT
Due to a large code generated class (LocalCacheFactory, 54K LOC), Eclipse will regularly freeze while it refreshes the project. It also has a slow build time.

Reproduce
1. git clone https://github.com/ben-manes/caffeine
2. ./gradlew build -x test
3. Import (via STS plugin)
Comment 1 Stephan Herrmann CLA 2015-10-01 05:10:27 EDT
I tried but didn't get very far:

FAILURE: Build failed with an exception.

* Where:
Build file '/home/stephan/jdt/bugs/bug478754/caffeine/build.gradle' line: 11

* What went wrong:
A problem occurred evaluating root project 'caffeine'.
> Could not find method jcenter() for arguments [] on repository container.


For a start: could you please attach the generated class?
Comment 2 Benjamin Manes CLA 2015-10-01 13:04:31 EDT
Created attachment 256975 [details]
Generated file
Comment 3 Benjamin Manes CLA 2015-10-01 13:09:14 EDT
Thanks for giving it a try.

I suspect you have an old version of Gradle installed and used it. If you use the gradlew shell script then it will auto-install the correct version into Gradle's cache and launch it. This way the build is tied to a known version.

The generated file is a little excessive. I was generating per-entry types and tried to do it for the main class too, to avoid unnecessary fields. That turned out to have more permutations than I anticipated, so it is a kind of ridiculous.
Comment 4 Stephan Herrmann CLA 2015-10-01 16:22:03 EDT
Looking at the generated class, for one thing this sure is a stress test for diamond inference.

Given that the class is generated, I wonder if you could do the following experiment: generate this class without any fields and methods except for the first newBoundedLocalCache() with its giant switch-case.

It would be very interesting to see, if just this switch-case together with empty declarations for the referenced classes reproduces the performance issue as well.
Comment 5 Benjamin Manes CLA 2015-10-01 22:01:26 EDT
It is definitely more responsive. It used to freeze, which no longer occurs. The refresh and compilation for even small changes (e.g. change a config file) can still take a while but it is much faster.

The refresh seems to spend a long time on "build/jacoco/classpathdumps". This is where all the class files seen by jacoco during a build are stored. I'd probably have to mark this as derived in order to get Eclipse to ignore it. After I deleted the jacoco folder, I can't seem to reproduce a degradation.

Would it be better to generate each of the static (nested) classes as top-level classes? I would have thought that there wouldn't be a big difference, since new class files are generated, but perhaps there's a subtle aspect of the JLS that I'm missing. I have noticed long delays due to the byte code verifier and have "-noverify" set for the build.
Comment 6 Benjamin Manes CLA 2015-10-03 00:47:05 EDT
After setting the class directories as derived, I haven't experienced any problems [1]. While the code generation did affect Ecliose's refresh and build times, the culprit seems to be somehow related to an explosion of having indexed all of the build data. I'm going to close this as I think the build should have been smarter, not Eclipse.

I had run into this issue a few years ago at work, resolved and forgot about it, and then rediscovered my own posting when searching for marking the build as derived. :)

[1] https://github.com/ben-manes/caffeine/blob/master/gradle/eclipse.gradle
Comment 7 Stephan Herrmann CLA 2015-10-03 08:03:22 EDT
Are you using BuildShip (the new gradle - Eclipse integration)? They *might* take care of automatically setting build/ as derived.
Comment 8 Benjamin Manes CLA 2015-10-03 17:02:29 EDT
When I tried an earlier version of Buildship, I filed a bug on its lack of hierarchical project and deduping support breaking my build. This was fixed in 1.5, but requires Gradle 1.8. The current 1.8-rc-1 broke my build's generation of the OSGi manifest due to a bnd version issue (method not found), so they'll be releasing rc-2 shortly with that fix. Perhaps then Buildship will be able to replace the STS plugin.

Regardless, I suspect that Buildship lacks this behavior because Gradle's Eclipse plugin doesn't do it either. Most likely I'll need my `.project` xml rewrites regardless of the tooling for the foreseeable future.