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
Enhancement request: public static final variables cause full recompilation of project #13493
Comments
Gradle used to analyze the constants in use but the analysis was wrong. See #1474 for context. Basically, the compilers inline constants, so we can't track where they come from. Imagine your code contains something like this:
and A.CONST_X = 2. Then the compiler will inline the result of the computation, and the body of the method will, bytecode-wise, be equivalent to:
We don't have any information to let us know that it came from This is why we said that whenever a class which has a constant changes, we need to rebuild everything. The point in this ticket is "but my constants didn't change and you still recompiled everything". That's because while we keep track of constants, we don't keep track of what symbol is used. So, say
and that it's changed to:
in both cases, the constant set is Does it mean we can't do anything? No. First of all, we could detect that the compiler you are using is actually one of those keeping track of inlined constants. I think this should be the case for all JDK 9+ compilers, but we need to double check that. Second, for every Java 8+ compiler that we call using the API, we use a compiler plugin to perform some incremental compilation analysis. It means we could actually register where the constants come from in this case. The problem is that we don't always use the compiler API. |
That would be an awesome improvement to build times in our case. The problem is, that constants sometimes need to be inlined (switch statements, annotation parameters etc) so you cannot workaround it with Also I believe constants are really common in Java projects which probably means that full recompilation due to constants is one of the top reasons why incremental compilation was not possible with Gradle. |
Currently, as soon as you have a project that has a public static final variable, Gradle will automatically recompile the entire project, even if that constant hasn't changed and the project only contains a single unrelated class change.
Expected Behavior
It would be nice if Gradle could tell whether the constant was really changed or not and avoid full recompilation.
Or if this is not possible, it would be nice if there was a toggle/mode with incremental recompilation with Gradle where we could choose to trade this full recompilation in exchange for only changed file recompilation. This would be really useful to achieve fast IDE iteration times.
Current Behavior
Full recompilation as soon as you change a file in a sourceSet that has a public static final variable.
Context
We are trying to move from the old
idea
IntelliJ integration (where IntelliJ does the compilation) to the native Gradle+IntelliJ integration, however a significant blocker is the re-compilation time that this introduces since Gradle recompiles much more than only the changed files due to this quirk.Our mono repo build currently has ~30k instances of this use case (+another 10k in generated code). As much as it might be considered "bad practice", they appear to be here to stay and are in almost every project.
Steps to Reproduce
Self-contained project attached. Note that
maven
behaves differently as well, pom included in the repro project.Your Environment
macOS / Java 11 / Gradle 6
gradle_incremental_compilation.zip
The text was updated successfully, but these errors were encountered: