-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Work around Gradle modifying system properties at configuration time #30210
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
When compiling Kotlin scripts, Gradle sets up some system properties. However, because Gradle doesn't instrument the Kotlin runtime, these modifications go unnoticed to environment change tracker infrastructure. If any user code then observes these system properties after modification, it becomes part of the configuration cache fingerprint. Moreover, as nothing restores the changed values when checking the fingerprint, it never matches, causing a CC miss. We can figure out the fixed set of properties set by the compiler and ignore them, but this set comes from the Kotlin (==third party) code so we'll have to maintain it and update alongside Kotlin releases. Instrumenting the Kotlin runtime to track system property updates in a usual way is an option, but it is much more involved and can bring in many unwanted inputs because of the Gradle runtime calling the Kotlin's stdlib functions. Restoring the system properties after compilation completes may also work but introduces a potential for race conditions when other, instrumented code may modify the system properties concurrently. Rolling back that changes would be an error.
The KotlinCompilerEnvironment instance serves as a token to mark all functions that may change the environment to configure the compiler. It also separates the tracking setup from the code in KotlinCompiler.
4b700ea
to
1b72e9f
Compare
@bot-gradle test ACC |
I've triggered the following builds for you. Click here to see all build failures. |
@bot-gradle test this |
I've triggered the following builds for you. Click here to see all build failures. |
|
||
buildFile("plugin/build.gradle", """ | ||
plugins { | ||
id "org.gradle.kotlin.kotlin-dsl" version "5.1.0" // TODO(mlopatkin): this should be the "current" Kotlin DSL version but it isn't available for Groovy scripts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💭 Could not find another way to apply kotlin-dsl plugin with Groovy DSL.
@@ -177,10 196,31 @@ class ConfigurationCacheEnvironmentChangeTracker(private val problemFactory: Pro | |||
systemPropertiesCleared = true | |||
mutatedSystemProperties.clear() | |||
} | |||
|
|||
override fun <T : Any> withTrackingSystemPropertyChanges(action: Supplier<out T>): T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☝️ This is the core non-trivial change.
When compiling Kotlin scripts, Gradle sets up some system properties. However, because Gradle doesn't instrument the Kotlin runtime, these modifications go unnoticed to environment change tracker infrastructure. If any user code then observes these system properties after modification, it becomes part of the configuration cache fingerprint. Moreover, as nothing restores the changed values when checking the fingerprint, it never matches, causing a CC miss.
With this PR, a special "scope function" of EnvironmentChangeTracker can be used to detect changes made to system properties and update the state of the tracker accordingly. This isn't a perfect solution for concurrent use cases, but it should work well when there is only one "scope" that modifies system properties directly, and everything else is instrumented.
It is possible to enter the scope function after restoring the CC state, for example, for a precompiled script plugin project. There is no change tracking in this case.
Fixes #30145.
Reviewing cheatsheet
Before merging the PR, comments starting with