Fix for illegal mutation issue with predeclareDeps#2892
Merged
nedtwigg merged 5 commits intodiffplug:mainfrom Mar 18, 2026
Merged
Fix for illegal mutation issue with predeclareDeps#2892nedtwigg merged 5 commits intodiffplug:mainfrom
predeclareDeps#2892nedtwigg merged 5 commits intodiffplug:mainfrom
Conversation
…Deps() with format tasks Store the `RegisterDependenciesTask` reference in `SpotlessTaskService` at configuration time instead of querying the task container via `withType()` during task realization, which triggers Gradle's mutation guard on 8.14+. Note that `withType(Class, Action)` and `withType(Class).configureEach(Action)` both trigger Gradle's `DefaultMutationGuard` when called during task realization (in Gradle 8.14+, maybe earlier). Fixes diffplug#2885
…upported with the fix
Member
|
This needs an update to the changelog in |
inorichi
reviewed
Mar 18, 2026
plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskService.java
Outdated
Show resolved
Hide resolved
Contributor
|
LGTM, and if predeclaredDeps is now supported by isolated projects, even better. I left a comment for a minor change. |
Contributor
Author
|
Done I updated the changes, if that's alright with you. |
inorichi
approved these changes
Mar 18, 2026
Member
|
Published in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix
IllegalMutationExceptionwhen root project usespredeclareDeps()with format tasksFixes
Introduced by
Problem
PR #2854 ("Partially support isolated projects") refactored
SpotlessTaskService.hookSubprojectTaskto look up theRegisterDependenciesTaskdynamically via the task container rather than holding a direct reference. The call usedwithType(Class, Action):On Gradle 8.14.x (unsure about the exact version this behavior was introduced), this throws
IllegalMutationExceptionwhen all the following are true:predeclareDeps()groovyGradle)During root project task realization, Gradle activates its mutation guard on the root task container.
The
configurecallback callsFormatExtension.setupTask()thenhookSubprojectTask()thenproject.getRootProject().getTasks().withType(Class, Action)on that same guarded container which Gradle forbids.Switching to
withType(Class).configureEach(Action)does not help either as Gradle also considersconfigureEacha mutating registration in this context.Fix
Since
RegisterDependenciesTaskis the task that must run before all projects, this fix assumes it can be safely referenced by the main spotless service. So the fix stores theRegisterDependenciesTaskreference directly inSpotlessTaskServiceat configuration time (whenSpotlessExtensionPredeclareis constructed andisUsingPredeclared()is set). ThenhookSubprojectTaskuses that reference directly, with no task container lookup during task realization.The
RegisterDependenciesTaskreference is already computed eagerly inSpotlessExtensionPredeclare(viafindRegisterDepsTask().get()), so no new eagerness is introduced.Note that
IsolatedProjectTest.predeclaredIsUnsupported()(introduced in #2854) expected a build failure that no longer occurs because this fix`Verification
Added
MultiProjectTest.predeclaredDepsRegression()that reproduces the exact trigger conditions and runs against Gradle 8.14.