dependencyUpdates task fails with ConcurrentModificationException since 0.52.0 in certain projects
I am getting a ConcurrentModificationException when running the dependencyUpdates task in some of my Spring Boot projects after upgrading them to gradle-versions-plugin v0.52.0. After some experimentation, I've narrowed it down to projects which use all 3 of these plugins:
io.spring.dependency-management, any version since at least v3.1.0info.solidsoft.pitestv1.15.0com.github.ben-manes.versionsv0.52.0
The relevant bit of the stack trace (I can copy the whole thing here if you'd like):
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':dependencyUpdates'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:130)
at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:293)
<snip>
Caused by: java.util.ConcurrentModificationException
at org.gradle.api.internal.collections.FilteredElementSource$FilteringIterator.findNext(FilteredElementSource.java:115)
at org.gradle.api.internal.collections.FilteredElementSource$FilteringIterator.next(FilteredElementSource.java:134)
at org.gradle.api.internal.DefaultDomainObjectCollection$IteratorImpl.next(DefaultDomainObjectCollection.java:494)
at com.github.benmanes.gradle.versions.updates.DependencyUpdates.resolveProjects(DependencyUpdates.kt:78)
at com.github.benmanes.gradle.versions.updates.DependencyUpdates.run(DependencyUpdates.kt:46)
at com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask.dependencyUpdates(DependencyUpdatesTask.kt:140)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:125)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:58)
<snip>
Crashing line: DependencyUpdates.kt:78
I have a minimal reproducer here: https://github.com/mitchellmebane/gradle-versions-plugin-crash/
This sounds like it might have been caused by the fix to #907, or perhaps that fix just moved the weak point into the loop in resolveProjects and changed the timing enough that my projects only hit it now.
I don't know much about Gradle internals, but I'll try and dig into this more if I have time.
ugh, sorry to hear that @mitchellmebane. I think you're right that it is the same as #907 and simply shifted the problem to now impact you. I believe this is a Gradle bug and that you may need to open an issue with them. The logic of their custom collection is confusing with these lazy side-effects that invalidate the iterator. From what I could tell, that iterator was in their code so any fix would be internal rather than by a plugin, so I'm skeptical that we can give you a proper workaround.
val projectConfigs =
project.allprojects
.associateBy({ it }, { it.configurations.matching(filterConfigurations) })
That's the source of the data. Looks like the actual type of projectConfigs is Map<Project, NamedDomainObjectSet<Configuration>>. NamedDomainObjectSet is a subtype of DomainObjectCollection, about which the docs say:
DomainObjectCollectioninstances are not thread-safe and undefined behavior may result from the invocation of any method on a collection that is being mutated by another thread; this includes direct invocations, passing the collection to a method that might perform invocations, and using an existing iterator to examine the collection.
which probably explains the issue.
It might be possible to change resolveProjects to take projectConfigs as a Map<Project, DomainObjectCollection<Configuration>>, and then use DomainObjectCollection.all instead of the loop. However, it's not clear from the documentation if that method is fully asynchronous, synchronous-for-things-currently-in-the-collection-and-then-async, or what. I'll do some more digging.
I was thinking that the realizePending was adding to the collection, which invalidated any existing iterators by incrementing the mod count. This wouldn’t be a threading issue, but that modifications must go through the iterator in typical collections. Java’s concurrent collections use weakly consistent iterators, but non-concurrent throw CME for misuse rather than concurrency. That was my assumption last time I looked, but your rationale is interesting too. At execution time I didn’t expect this to be modified, only at init/configuration build phases.
I was thinking that the realizePending was adding to the collection
Hm, that might be possible. I don't have a good feel for how all the lazy initialization works in Gradle yet.
This wouldn’t be a threading issue
Right, that would be a reentrancy issue. I guess I tend to conflate them in my mind. The good news is that if it's not caused by multi-threading, I can probably write a deterministic test case, if I can find what behavior is triggering the crash.
At execution time I didn’t expect this to be modified, only at init/configuration build phases.
Yes, that's definitely what I would expect after reading the Build Lifecycle documentation. I'm going to dig through the other two plugins in my repro project and see if they're modifying the configurations anywhere weird.
Based on some simple print debugging, it looks like the runtime type of currentConfigurations is org.gradle.api.internal.DefaultNamedDomainObjectSet_Decorated.
DefaultNamedDomainObjectSet's iterator() implementation is DefaultDomainObjectCollection#iterator, which mostly just delegates to the backing store, which at runtime is FilteredElementSource#iterator. That implementation calls realizePending before starting iteration, which makes me think something else is modifying the configurations later, during the iteration - but I'm still learning most of this as I go, so 🤷.
I'll have to set up a real debugger tonight and look more closely.
It has been a while since I attached a debugger directly to Gradle, but here are my notes.
In some cases the tasks accept --debug-jvm. Unfortunately I think this is only for test tasks to do the bootstrap for you.
More generally, for any Java program, you can use a remote attachment. In my projects, before that flag above, I used to use
if ("debug" in systemProperties) {
jvmArgs("-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005")
}
IntelliJ may have this built in now and it can all be done directly and understands their kts support. When I first wrote this plugin in groovy on gradle 1.0, IntelliJ had no support and Eclipse's was vastly superior thanks to Spring's plugin. At that time, when print debugging was not enough, I was able to step through this way (I think this was to pinpoint a bug in their repository handler that dropped maven repos by incorrect deduplication). hope this helps.
IntelliJ is much smarter about this today indeed. I created a separate composite build with my repro project and the plugin project, imported it into IntelliJ, and can set breakpoints in the plugin while starting a debug of the dependencyUpdates task in the repro, and it all just works.
And there is, in fact, a modification of the configurations set during processing. When processing the testCompileClasspath configuration, this line triggers the addition of a tmpTestImplementation configuration:
val lenient = copy.resolvedConfiguration.lenientConfiguration
That tmpTestImplemenation configuration is being added in gradle-pitest-plugin: PitestPlugin.groovy:267
Here's the call stack when that line is hit:
Stack Trace
doCall$original:267, PitestPlugin$_addJUnitPlatformLauncherDependencyIfNeeded_closure12$_closure16 (info.solidsoft.gradle.pitest)
doCall:-1, PitestPlugin$_addJUnitPlatformLauncherDependencyIfNeeded_closure12$_closure16 (info.solidsoft.gradle.pitest)
invokeSpecial:-1, DirectMethodHandle$Holder (java.lang.invoke)
invoke:-1, LambdaForm$MH/0x000000fc01098000 (java.lang.invoke)
invokeExact_MT:-1, Invokers$Holder (java.lang.invoke)
invokeImpl:154, DirectMethodHandleAccessor (jdk.internal.reflect)
invoke:103, DirectMethodHandleAccessor (jdk.internal.reflect)
invoke:580, Method (java.lang.reflect)
invoke:107, CachedMethod (org.codehaus.groovy.reflection)
doMethodInvoke:323, MetaMethod (groovy.lang)
invokeMethod:274, ClosureMetaClass (org.codehaus.groovy.runtime.metaclass)
invokeMethod:1030, MetaClassImpl (groovy.lang)
call:427, Closure (groovy.lang)
invokeCustom:50, ConvertedClosure (org.codehaus.groovy.runtime)
invoke:112, ConversionHandler (org.codehaus.groovy.runtime)
execute:-1, $Proxy124 (jdk.proxy1)
execute:285, ImmutableActionSet$SetWithFewActions (org.gradle.internal)
lambda$runDependencyActions$2:495, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
execute:-1, DefaultConfiguration$$Lambda/0x000000fc016a79e8 (org.gradle.api.internal.artifacts.configurations)
runActionInHierarchy:1197, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
runDependencyActions:493, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
getDependencies:1906, DefaultConfiguration$ConfigurationResolvableDependencies (org.gradle.api.internal.artifacts.configurations)
getDependencies:-1, DefaultConfiguration$ConfigurationResolvableDependencies_Decorated (org.gradle.api.internal.artifacts.configurations)
getVersionedModuleDependencies:83, ImplicitDependencyManagementCollector (io.spring.gradle.dependencymanagement.internal)
processConfiguration:67, ImplicitDependencyManagementCollector (io.spring.gradle.dependencymanagement.internal)
accept:-1, ImplicitDependencyManagementCollector$$Lambda/0x000000fc01d6d7a0 (io.spring.gradle.dependencymanagement.internal)
forEach:75, Iterable (java.lang)
lambda$execute$0:61, ImplicitDependencyManagementCollector (io.spring.gradle.dependencymanagement.internal)
execute:-1, ImplicitDependencyManagementCollector$$Lambda/0x000000fc01cf9b78 (io.spring.gradle.dependencymanagement.internal)
execute:124, DefaultUserCodeApplicationContext$CurrentApplication$1 (org.gradle.internal.code)
dispatch:99, BroadcastDispatch$ActionInvocationHandler (org.gradle.internal.event)
dispatch:87, BroadcastDispatch$ActionInvocationHandler (org.gradle.internal.event)
dispatch:44, AbstractBroadcastDispatch (org.gradle.internal.event)
dispatch:268, BroadcastDispatch$SingletonDispatch (org.gradle.internal.event)
dispatch:170, BroadcastDispatch$SingletonDispatch (org.gradle.internal.event)
dispatch:84, AbstractBroadcastDispatch (org.gradle.internal.event)
dispatch:70, AbstractBroadcastDispatch (org.gradle.internal.event)
dispatch:380, BroadcastDispatch$CompositeDispatch (org.gradle.internal.event)
dispatch:272, BroadcastDispatch$CompositeDispatch (org.gradle.internal.event)
dispatch:153, ListenerBroadcast (org.gradle.internal.event)
dispatch:38, ListenerBroadcast (org.gradle.internal.event)
invoke:92, ProxyDispatchAdapter$DispatchingInvocationHandler (org.gradle.internal.dispatch)
beforeResolve:-1, $Proxy65 (jdk.proxy1)
runBeforeResolve:912, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
access$1300:159, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
call:781, DefaultConfiguration$1 (org.gradle.api.internal.artifacts.configurations)
call:777, DefaultConfiguration$1 (org.gradle.api.internal.artifacts.configurations)
execute:209, DefaultBuildOperationRunner$CallableBuildOperationWorker (org.gradle.internal.operations)
execute:204, DefaultBuildOperationRunner$CallableBuildOperationWorker (org.gradle.internal.operations)
execute:66, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:166, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner (org.gradle.internal.operations)
call:53, DefaultBuildOperationRunner (org.gradle.internal.operations)
resolveGraphInBuildOperation:777, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
lambda$resolveExclusivelyIfRequired$5:769, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
apply:-1, DefaultConfiguration$$Lambda/0x000000fc016c55f8 (org.gradle.api.internal.artifacts.configurations)
update:509, DefaultProjectStateRegistry$CalculatedModelValueImpl (org.gradle.api.internal.project)
resolveExclusivelyIfRequired:764, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
resolveGraphIfRequired:757, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
access$1200:159, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
getValue:731, DefaultConfiguration$ResolverResultsResolutionResultProvider (org.gradle.api.internal.artifacts.configurations)
getValue:692, DefaultConfiguration$ResolverResultsResolutionResultProvider (org.gradle.api.internal.artifacts.configurations)
getResolvedConfiguration:646, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
getResolvedConfiguration:-1, DefaultUnlockedConfiguration_Decorated (org.gradle.api.internal.artifacts.configurations)
getCurrentCoordinates:279, Resolver (com.github.benmanes.gradle.versions.updates)
resolve:56, Resolver (com.github.benmanes.gradle.versions.updates)
resolve:101, DependencyUpdates (com.github.benmanes.gradle.versions.updates)
lambda 'forEach' in 'resolveProjects':86, DependencyUpdates (com.github.benmanes.gradle.versions.updates)
forEach:215, DependencyUpdates (com.github.benmanes.gradle.versions.updates)
resolveProjects:79, DependencyUpdates (com.github.benmanes.gradle.versions.updates)
run:49, DependencyUpdates (com.github.benmanes.gradle.versions.updates)
dependencyUpdates:140, DependencyUpdatesTask (com.github.benmanes.gradle.versions.updates)
invokeSpecial:-1, DirectMethodHandle$Holder (java.lang.invoke)
invoke:-1, LambdaForm$MH/0x000000fc01220800 (java.lang.invoke)
invokeExact_MT:-1, Invokers$Holder (java.lang.invoke)
invokeImpl:153, DirectMethodHandleAccessor (jdk.internal.reflect)
invoke:103, DirectMethodHandleAccessor (jdk.internal.reflect)
invoke:580, Method (java.lang.reflect)
invoke:125, JavaMethod (org.gradle.internal.reflect)
doExecute:58, StandardTaskAction (org.gradle.api.internal.project.taskfactory)
execute:51, StandardTaskAction (org.gradle.api.internal.project.taskfactory)
execute:29, StandardTaskAction (org.gradle.api.internal.project.taskfactory)
run:244, TaskExecution$3 (org.gradle.api.internal.tasks.execution)
execute:29, DefaultBuildOperationRunner$1 (org.gradle.internal.operations)
execute:26, DefaultBuildOperationRunner$1 (org.gradle.internal.operations)
execute:66, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:166, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner (org.gradle.internal.operations)
run:47, DefaultBuildOperationRunner (org.gradle.internal.operations)
executeAction:229, TaskExecution (org.gradle.api.internal.tasks.execution)
executeActions:212, TaskExecution (org.gradle.api.internal.tasks.execution)
executeWithPreviousOutputFiles:195, TaskExecution (org.gradle.api.internal.tasks.execution)
execute:162, TaskExecution (org.gradle.api.internal.tasks.execution)
executeInternal:105, ExecuteStep (org.gradle.internal.execution.steps)
access$000:44, ExecuteStep (org.gradle.internal.execution.steps)
call:59, ExecuteStep$1 (org.gradle.internal.execution.steps)
call:56, ExecuteStep$1 (org.gradle.internal.execution.steps)
execute:209, DefaultBuildOperationRunner$CallableBuildOperationWorker (org.gradle.internal.operations)
execute:204, DefaultBuildOperationRunner$CallableBuildOperationWorker (org.gradle.internal.operations)
execute:66, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:166, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner (org.gradle.internal.operations)
call:53, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:56, ExecuteStep (org.gradle.internal.execution.steps)
execute:44, ExecuteStep (org.gradle.internal.execution.steps)
execute:42, CancelExecutionStep (org.gradle.internal.execution.steps)
executeWithoutTimeout:75, TimeoutStep (org.gradle.internal.execution.steps)
execute:55, TimeoutStep (org.gradle.internal.execution.steps)
execute:50, PreCreateOutputParentsStep (org.gradle.internal.execution.steps)
execute:28, PreCreateOutputParentsStep (org.gradle.internal.execution.steps)
execute:67, RemovePreviousOutputsStep (org.gradle.internal.execution.steps)
execute:37, RemovePreviousOutputsStep (org.gradle.internal.execution.steps)
execute:61, BroadcastChangingOutputsStep (org.gradle.internal.execution.steps)
execute:26, BroadcastChangingOutputsStep (org.gradle.internal.execution.steps)
execute:69, CaptureOutputsAfterExecutionStep (org.gradle.internal.execution.steps)
execute:46, CaptureOutputsAfterExecutionStep (org.gradle.internal.execution.steps)
execute:40, ResolveInputChangesStep (org.gradle.internal.execution.steps)
execute:29, ResolveInputChangesStep (org.gradle.internal.execution.steps)
executeWithoutCache:189, BuildCacheStep (org.gradle.internal.execution.steps)
lambda$execute$1:75, BuildCacheStep (org.gradle.internal.execution.steps)
apply:-1, BuildCacheStep$$Lambda/0x000000fc01d63a10 (org.gradle.internal.execution.steps)
fold:175, Either$Right (org.gradle.internal)
fold:62, CachingState (org.gradle.internal.execution.caching)
execute:73, BuildCacheStep (org.gradle.internal.execution.steps)
execute:48, BuildCacheStep (org.gradle.internal.execution.steps)
execute:46, StoreExecutionStateStep (org.gradle.internal.execution.steps)
execute:35, StoreExecutionStateStep (org.gradle.internal.execution.steps)
executeBecause:75, SkipUpToDateStep (org.gradle.internal.execution.steps)
lambda$execute$2:53, SkipUpToDateStep (org.gradle.internal.execution.steps)
get:-1, SkipUpToDateStep$$Lambda/0x000000fc01cdd598 (org.gradle.internal.execution.steps)
orElseGet:364, Optional (java.util)
execute:53, SkipUpToDateStep (org.gradle.internal.execution.steps)
execute:35, SkipUpToDateStep (org.gradle.internal.execution.steps)
execute:37, MarkSnapshottingInputsFinishedStep (org.gradle.internal.execution.steps.legacy)
execute:27, MarkSnapshottingInputsFinishedStep (org.gradle.internal.execution.steps.legacy)
executeDelegate:49, ResolveIncrementalCachingStateStep (org.gradle.internal.execution.steps)
executeDelegate:27, ResolveIncrementalCachingStateStep (org.gradle.internal.execution.steps)
execute:71, AbstractResolveCachingStateStep (org.gradle.internal.execution.steps)
execute:39, AbstractResolveCachingStateStep (org.gradle.internal.execution.steps)
execute:65, ResolveChangesStep (org.gradle.internal.execution.steps)
execute:36, ResolveChangesStep (org.gradle.internal.execution.steps)
execute:107, ValidateStep (org.gradle.internal.execution.steps)
execute:56, ValidateStep (org.gradle.internal.execution.steps)
execute:64, AbstractCaptureStateBeforeExecutionStep (org.gradle.internal.execution.steps)
execute:43, AbstractCaptureStateBeforeExecutionStep (org.gradle.internal.execution.steps)
executeWithNonEmptySources:125, AbstractSkipEmptyWorkStep (org.gradle.internal.execution.steps)
execute:56, AbstractSkipEmptyWorkStep (org.gradle.internal.execution.steps)
execute:36, AbstractSkipEmptyWorkStep (org.gradle.internal.execution.steps)
execute:38, MarkSnapshottingInputsStartedStep (org.gradle.internal.execution.steps.legacy)
execute:36, LoadPreviousExecutionStateStep (org.gradle.internal.execution.steps)
execute:23, LoadPreviousExecutionStateStep (org.gradle.internal.execution.steps)
execute:75, HandleStaleOutputsStep (org.gradle.internal.execution.steps)
execute:41, HandleStaleOutputsStep (org.gradle.internal.execution.steps)
lambda$execute$0:35, AssignMutableWorkspaceStep (org.gradle.internal.execution.steps)
executeInWorkspace:-1, AssignMutableWorkspaceStep$$Lambda/0x000000fc01cbb698 (org.gradle.internal.execution.steps)
withWorkspace:289, TaskExecution$4 (org.gradle.api.internal.tasks.execution)
execute:31, AssignMutableWorkspaceStep (org.gradle.internal.execution.steps)
execute:22, AssignMutableWorkspaceStep (org.gradle.internal.execution.steps)
execute:40, ChoosePipelineStep (org.gradle.internal.execution.steps)
execute:23, ChoosePipelineStep (org.gradle.internal.execution.steps)
lambda$execute$2:67, ExecuteWorkBuildOperationFiringStep (org.gradle.internal.execution.steps)
get:-1, ExecuteWorkBuildOperationFiringStep$$Lambda/0x000000fc014ddb30 (org.gradle.internal.execution.steps)
orElseGet:364, Optional (java.util)
execute:67, ExecuteWorkBuildOperationFiringStep (org.gradle.internal.execution.steps)
execute:39, ExecuteWorkBuildOperationFiringStep (org.gradle.internal.execution.steps)
execute:46, IdentityCacheStep (org.gradle.internal.execution.steps)
execute:34, IdentityCacheStep (org.gradle.internal.execution.steps)
execute:48, IdentifyStep (org.gradle.internal.execution.steps)
execute:35, IdentifyStep (org.gradle.internal.execution.steps)
execute:61, DefaultExecutionEngine$1 (org.gradle.internal.execution.impl)
executeIfValid:127, ExecuteActionsTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:116, ExecuteActionsTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:46, FinalizePropertiesTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:51, ResolveTaskExecutionModeExecuter (org.gradle.api.internal.tasks.execution)
execute:57, SkipTaskWithNoActionsExecuter (org.gradle.api.internal.tasks.execution)
execute:74, SkipOnlyIfTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:36, CatchExceptionTaskExecuter (org.gradle.api.internal.tasks.execution)
executeTask:77, EventFiringTaskExecuter$1 (org.gradle.api.internal.tasks.execution)
call:55, EventFiringTaskExecuter$1 (org.gradle.api.internal.tasks.execution)
call:52, EventFiringTaskExecuter$1 (org.gradle.api.internal.tasks.execution)
execute:209, DefaultBuildOperationRunner$CallableBuildOperationWorker (org.gradle.internal.operations)
execute:204, DefaultBuildOperationRunner$CallableBuildOperationWorker (org.gradle.internal.operations)
execute:66, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:166, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner (org.gradle.internal.operations)
call:53, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:52, EventFiringTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:42, LocalTaskNodeExecutor (org.gradle.execution.plan)
execute:331, DefaultTaskExecutionGraph$InvokeNodeExecutorsAction (org.gradle.execution.taskgraph)
execute:318, DefaultTaskExecutionGraph$InvokeNodeExecutorsAction (org.gradle.execution.taskgraph)
lambda$execute$0:314, DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction (org.gradle.execution.taskgraph)
run:-1, DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction$$Lambda/0x000000fc01c93000 (org.gradle.execution.taskgraph)
with:85, CurrentBuildOperationRef (org.gradle.internal.operations)
execute:314, DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction (org.gradle.execution.taskgraph)
execute:303, DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction (org.gradle.execution.taskgraph)
execute:459, DefaultPlanExecutor$ExecutorWorker (org.gradle.execution.plan)
run:376, DefaultPlanExecutor$ExecutorWorker (org.gradle.execution.plan)
onExecute:64, ExecutorPolicy$CatchAndRecordFailures (org.gradle.internal.concurrent)
run:48, AbstractManagedExecutor$1 (org.gradle.internal.concurrent)
runWorker:1144, ThreadPoolExecutor (java.util.concurrent)
run:642, ThreadPoolExecutor$Worker (java.util.concurrent)
runWith:1588, Thread (java.lang)
run:1575, Thread (java.lang)
You can see the execution flows through the io.spring.dependency-management plugin. And if I remove that plugin from my project, that configuration in the pitest plugin doesn't run and the tmpTestImplementation configuration is not added.
I guess I'll have to look at the io.spring.dependency-management plugin next.
It seems odd that they would add a configuration during dependency resolution? The withDependencies would be invoked when that configuration is being resolved, which then adds another configuration with more dependencies to the project. I could understand if it was a detached configuration, but here it is added to the project's configuration container at execution time which is invalid. If they are trying to resolve the configuration, then how we do it would make more sense? They modify the test configuration by adding a dependency to it, which may by chance be done before it was resolved since that likely depends on the testImplementation being evaluated. It seems like a very weird hack to me to implicitly add a dependency when it would otherwise be explicit. It is a confusing approach which I think typically a default dependency would be more straightforward.
I know a little about the io.spring.dependency-management as it handles BOM management. There was previously an issue with their resolution strategy not allowing us to query for dynamic versions. They were very responsive, helpful, and quickly resolved their issues.
I would guess that the spring plugin is adding the junit dependency via its BOM, and that triggers pitest to do this crazy logic.
I have this problem since upgrade to Gradle 9.0.
- com.github.ben-manes.versions v0.52.0
- quarkus 3.25.2
9.0 works for me using —no-parallel but that build doesn’t use quarkus.
I tried it, but this workaround does change the outcome.
gradlew dependencyUpdates --no-parallel
FAILURE: Build failed with an exception.
- What went wrong: Execution failed for task ':dependencyUpdates'.
java.util.ConcurrentModificationException
Previously you found it was gradle-pitest-plugin modifying the configuration at execution time in an unsafe manner. Was that resolved?
Sorry, I think it was someone else. I only use dependencyUpdates. I don't use the pitest plugin (and I don't modify configs ;-))
Oh sorry. Above the issue was found to be another plugin modifying the configurations set during processing, which breaks the Gradle apis. There isn’t a way for this plugin to work around that, the other plugin must not corrupt the build state.
I'm also now facing this for a normal Android app, I've disabled nearly all possible plugins and out of idea to identify the root cause.
can you add a breakpoint to see what configuration is being created at execution time? You can see in the PitestPlugin.groovy linked above that they create a configuration as a side effect of other configurations, which leads to this ConcurrentModificationException when Gradle's lazy resolving in its iterator mutates the set. That plugin is performing unsafe logic so you might have something doing similar. A breakpoint in Gradle should show you where the culprit is that added to the set.
I can't get the composite working in Android Studio will try again next week.
Just as an FYI I ran into this today on a multimodule project using Gradle 9.0.0 And AS Narwhal 4 Canary 2. The project has four modules, three of which use dependencyUpdates plugin. Interestingly out of the three modules, one works fine, and the other two consistently fail with the ConcurrencyModificationException.
Unfortunately I've been away from this project, and did a bunch of version upgrading to it the last couple days,so I have no idea what change I made that is hitting this now. It use to work fine on all three modules until recent changes.
If there is something I can do to provide a diagnostic, lemme know.
The top of the call stack looks like this, it's the same stack as the original post above had:
Caused by: java.util.ConcurrentModificationException
at org.gradle.api.internal.collections.FilteredElementSource$FilteringIterator.findNext(FilteredElementSource.java:115)
at org.gradle.api.internal.collections.FilteredElementSource$FilteringIterator.next(FilteredElementSource.java:134)
at org.gradle.api.internal.DefaultDomainObjectCollection$IteratorImpl.next(DefaultDomainObjectCollection.java:494)
at com.github.benmanes.gradle.versions.updates.DependencyUpdates.resolveProjects(DependencyUpdates.kt:78)
at com.github.benmanes.gradle.versions.updates.DependencyUpdates.run(DependencyUpdates.kt:46)
at com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask.dependencyUpdates(DependencyUpdatesTask.kt:140)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:125)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:58)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:252)
I think you would either (a) need to attach a debugger to see what is adding to the configuration while its being resolved or (b) raise an issue with the Gradle team. I believe they would argue its a problem from (a) that needs to not modify add configurations during resolution because configurations are lazy now (were originally eager). However, they might be generous to say (b) for them to change their internal collection type be concurrent for a weakly consistent iterator. The problem is I can't help because the gradle-versions-plugin is merely using the Gradle public API and there isn't any real workaround. I think the best I could do is something ugly like catching and retrying a few times, which is fundamentally wrong since ConcurrentModificationException means the collection may be in an corrupted and unrecoverable state.
Also facing the same issue currently.
@ben-manes @mitchellmebane I'd like to attach a debugger, but I can't get the composite build working, it I attach this plugin's source code root as my project's included build I got the following error:
FAILURE: Build failed with an exception.
* What went wrong:
org.gradle.api.internal.catalog.GeneratedClassCompilationException: Unable to compile generated sources:
- File RootProjectAccessor.java, line: 29, method getGradleVersionsPlugin() is already defined in class org.gradle.accessors.dm.RootProjectAccessor
> Unable to compile generated sources:
- File RootProjectAccessor.java, line: 29, method getGradleVersionsPlugin() is already defined in class org.gradle.accessors.dm.RootProjectAccessor
* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to generate a Build Scan (Powered by Develocity).
> Get more help at https://help.gradle.org.
* Exception is:
java.lang.RuntimeException: org.gradle.api.internal.catalog.GeneratedClassCompilationException: Unable to compile generated sources:
- File RootProjectAccessor.java, line: 29, method getGradleVersionsPlugin() is already defined in class org.gradle.accessors.dm.RootProjectAccessor
at org.gradle.api.internal.catalog.DefaultDependenciesAccessors.generateAccessors(DefaultDependenciesAccessors.java:162)
at org.gradle.configuration.BuildTreePreparingProjectsPreparer.generateDependenciesAccessorsAndAssignPluginVersions(BuildTreePreparingProjectsPreparer.java:92)
at org.gradle.configuration.BuildTreePreparingProjectsPreparer.prepareProjects(BuildTreePreparingProjectsPreparer.java:55)
at org.gradle.configuration.BuildOperationFiringProjectsPreparer$ConfigureBuild.run(BuildOperationFiringProjectsPreparer.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
at org.gradle.configuration.BuildOperationFiringProjectsPreparer.prepareProjects(BuildOperationFiringProjectsPreparer.java:40)
at org.gradle.initialization.VintageBuildModelController.lambda$prepareProjects$2(VintageBuildModelController.java:83)
at org.gradle.internal.model.StateTransitionController.lambda$doTransition$14(StateTransitionController.java:255)
at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:254)
at org.gradle.internal.model.StateTransitionController.lambda$transitionIfNotPreviously$11(StateTransitionController.java:213)
at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:35)
at org.gradle.internal.model.StateTransitionController.transitionIfNotPreviously(StateTransitionController.java:209)
at org.gradle.initialization.VintageBuildModelController.prepareProjects(VintageBuildModelController.java:83)
at org.gradle.initialization.VintageBuildModelController.getConfiguredModel(VintageBuildModelController.java:63)
at org.gradle.internal.cc.impl.ConfigurationCacheAwareBuildModelController.getConfiguredModel(ConfigurationCacheAwareBuildModelController.kt:43)
at org.gradle.internal.model.StateTransitionController.lambda$notInState$3(StateTransitionController.java:132)
at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:45)
at org.gradle.internal.model.StateTransitionController.notInState(StateTransitionController.java:128)
at org.gradle.internal.build.DefaultBuildLifecycleController.configureProjects(DefaultBuildLifecycleController.java:128)
at org.gradle.internal.build.AbstractBuildState.ensureProjectsConfigured(AbstractBuildState.java:145)
at org.gradle.composite.internal.AbstractCompositeParticipantBuildState.ensureChildBuildConfigured(AbstractCompositeParticipantBuildState.java:61)
at org.gradle.composite.internal.AbstractCompositeParticipantBuildState.getAvailableModules(AbstractCompositeParticipantBuildState.java:51)
at org.gradle.composite.internal.IncludedBuildDependencySubstitutionsBuilder.build(IncludedBuildDependencySubstitutionsBuilder.java:83)
at org.gradle.composite.internal.IncludedBuildDependencySubstitutionsBuilder.registerSubstitutionsFor(IncludedBuildDependencySubstitutionsBuilder.java:64)
at org.gradle.internal.buildtree.BuildInclusionCoordinator.lambda$registerSubstitutionsFor$1(BuildInclusionCoordinator.java:143)
at org.gradle.internal.buildtree.BuildInclusionCoordinator$BuildSynchronizer.lambda$withLock$0(BuildInclusionCoordinator.java:66)
at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:35)
at org.gradle.internal.buildtree.BuildInclusionCoordinator$BuildSynchronizer.withLock(BuildInclusionCoordinator.java:60)
at org.gradle.internal.buildtree.BuildInclusionCoordinator.withLockForBuild(BuildInclusionCoordinator.java:147)
at org.gradle.internal.buildtree.BuildInclusionCoordinator.registerSubstitutionsFor(BuildInclusionCoordinator.java:143)
at org.gradle.internal.buildtree.BuildInclusionCoordinator.registerGlobalLibrarySubstitutions(BuildInclusionCoordinator.java:97)
at org.gradle.internal.buildtree.BuildInclusionCoordinator.registerSubstitutionsAvailableFor(BuildInclusionCoordinator.java:103)
at org.gradle.configuration.BuildTreePreparingProjectsPreparer.prepareProjects(BuildTreePreparingProjectsPreparer.java:60)
at org.gradle.configuration.BuildOperationFiringProjectsPreparer$ConfigureBuild.run(BuildOperationFiringProjectsPreparer.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
at org.gradle.configuration.BuildOperationFiringProjectsPreparer.prepareProjects(BuildOperationFiringProjectsPreparer.java:40)
at org.gradle.initialization.VintageBuildModelController.lambda$prepareProjects$2(VintageBuildModelController.java:83)
at org.gradle.internal.model.StateTransitionController.lambda$doTransition$14(StateTransitionController.java:255)
at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:254)
at org.gradle.internal.model.StateTransitionController.lambda$transitionIfNotPreviously$11(StateTransitionController.java:213)
at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:35)
at org.gradle.internal.model.StateTransitionController.transitionIfNotPreviously(StateTransitionController.java:209)
at org.gradle.initialization.VintageBuildModelController.prepareProjects(VintageBuildModelController.java:83)
at org.gradle.initialization.VintageBuildModelController.prepareToScheduleTasks(VintageBuildModelController.java:70)
at org.gradle.internal.cc.impl.ConfigurationCacheAwareBuildModelController.prepareToScheduleTasks(ConfigurationCacheAwareBuildModelController.kt:49)
at org.gradle.internal.build.DefaultBuildLifecycleController.lambda$prepareToScheduleTasks$6(DefaultBuildLifecycleController.java:175)
at org.gradle.internal.model.StateTransitionController.lambda$doTransition$14(StateTransitionController.java:255)
at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:254)
at org.gradle.internal.model.StateTransitionController.lambda$maybeTransition$9(StateTransitionController.java:190)
at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:35)
at org.gradle.internal.model.StateTransitionController.maybeTransition(StateTransitionController.java:186)
at org.gradle.internal.build.DefaultBuildLifecycleController.prepareToScheduleTasks(DefaultBuildLifecycleController.java:173)
at org.gradle.internal.buildtree.DefaultBuildTreeWorkPreparer.scheduleRequestedTasks(DefaultBuildTreeWorkPreparer.java:35)
at org.gradle.internal.cc.impl.ConfigurationCacheAwareBuildTreeWorkController$scheduleAndRunRequestedTasks$executionResult$1.apply$lambda$0(ConfigurationCacheAwareBuildTreeWorkController.kt:48)
at org.gradle.internal.cc.impl.DefaultConfigurationCache.loadOrScheduleRequestedTasks$lambda$10(DefaultConfigurationCache.kt:245)
at org.gradle.internal.cc.impl.DefaultConfigurationCache.runWorkThatContributesToCacheEntry(DefaultConfigurationCache.kt:576)
at org.gradle.internal.cc.impl.DefaultConfigurationCache.loadOrScheduleRequestedTasks(DefaultConfigurationCache.kt:244)
at org.gradle.internal.cc.impl.ConfigurationCacheAwareBuildTreeWorkController$scheduleAndRunRequestedTasks$executionResult$1.apply(ConfigurationCacheAwareBuildTreeWorkController.kt:45)
at org.gradle.internal.cc.impl.ConfigurationCacheAwareBuildTreeWorkController$scheduleAndRunRequestedTasks$executionResult$1.apply(ConfigurationCacheAwareBuildTreeWorkController.kt:44)
at org.gradle.composite.internal.DefaultIncludedBuildTaskGraph.withNewWorkGraph(DefaultIncludedBuildTaskGraph.java:113)
at org.gradle.internal.cc.impl.ConfigurationCacheAwareBuildTreeWorkController.scheduleAndRunRequestedTasks(ConfigurationCacheAwareBuildTreeWorkController.kt:44)
at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$scheduleAndRunTasks$1(DefaultBuildTreeLifecycleController.java:77)
at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$runBuild$4(DefaultBuildTreeLifecycleController.java:120)
at org.gradle.internal.model.StateTransitionController.lambda$transition$6(StateTransitionController.java:169)
at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:266)
at org.gradle.internal.model.StateTransitionController.lambda$transition$7(StateTransitionController.java:169)
at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:45)
at org.gradle.internal.model.StateTransitionController.transition(StateTransitionController.java:169)
at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.runBuild(DefaultBuildTreeLifecycleController.java:117)
at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.scheduleAndRunTasks(DefaultBuildTreeLifecycleController.java:77)
at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.scheduleAndRunTasks(DefaultBuildTreeLifecycleController.java:72)
at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:31)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.internal.buildtree.ProblemReportingBuildActionRunner.run(ProblemReportingBuildActionRunner.java:54)
at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:83)
at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:135)
at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:54)
at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.lambda$execute$0(RootBuildLifecycleBuildActionExecutor.java:56)
at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:130)
at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.execute(RootBuildLifecycleBuildActionExecutor.java:56)
at org.gradle.internal.buildtree.InitDeprecationLoggingActionExecutor.execute(InitDeprecationLoggingActionExecutor.java:62)
at org.gradle.internal.buildtree.InitProblems.execute(InitProblems.java:36)
at org.gradle.internal.buildtree.DefaultBuildTreeContext.execute(DefaultBuildTreeContext.java:40)
at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.lambda$execute$0(BuildTreeLifecycleBuildActionExecutor.java:71)
at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:60)
at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.execute(BuildTreeLifecycleBuildActionExecutor.java:71)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$2.call(RunAsBuildOperationBuildActionExecutor.java:65)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$2.call(RunAsBuildOperationBuildActionExecutor.java:61)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor.execute(RunAsBuildOperationBuildActionExecutor.java:61)
at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.lambda$execute$0(RunAsWorkerThreadBuildActionExecutor.java:36)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:263)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.execute(RunAsWorkerThreadBuildActionExecutor.java:36)
at org.gradle.tooling.internal.provider.continuous.ContinuousBuildActionExecutor.execute(ContinuousBuildActionExecutor.java:110)
at org.gradle.tooling.internal.provider.SubscribableBuildActionExecutor.execute(SubscribableBuildActionExecutor.java:64)
at org.gradle.internal.session.DefaultBuildSessionContext.execute(DefaultBuildSessionContext.java:46)
at org.gradle.internal.buildprocess.execution.BuildSessionLifecycleBuildActionExecutor$ActionImpl.apply(BuildSessionLifecycleBuildActionExecutor.java:92)
at org.gradle.internal.buildprocess.execution.BuildSessionLifecycleBuildActionExecutor$ActionImpl.apply(BuildSessionLifecycleBuildActionExecutor.java:80)
at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:73)
at org.gradle.internal.buildprocess.execution.BuildSessionLifecycleBuildActionExecutor.execute(BuildSessionLifecycleBuildActionExecutor.java:62)
at org.gradle.internal.buildprocess.execution.BuildSessionLifecycleBuildActionExecutor.execute(BuildSessionLifecycleBuildActionExecutor.java:41)
at org.gradle.internal.buildprocess.execution.StartParamsValidatingActionExecutor.execute(StartParamsValidatingActionExecutor.java:57)
at org.gradle.internal.buildprocess.execution.StartParamsValidatingActionExecutor.execute(StartParamsValidatingActionExecutor.java:32)
at org.gradle.internal.buildprocess.execution.SessionFailureReportingActionExecutor.execute(SessionFailureReportingActionExecutor.java:51)
at org.gradle.internal.buildprocess.execution.SessionFailureReportingActionExecutor.execute(SessionFailureReportingActionExecutor.java:39)
at org.gradle.internal.buildprocess.execution.SetupLoggingActionExecutor.execute(SetupLoggingActionExecutor.java:47)
at org.gradle.internal.buildprocess.execution.SetupLoggingActionExecutor.execute(SetupLoggingActionExecutor.java:31)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:70)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.lambda$execute$0(ForwardClientInput.java:40)
at org.gradle.internal.daemon.clientinput.ClientInputForwarder.forwardInput(ClientInputForwarder.java:80)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:64)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator.lambda$runCommand$0(DaemonStateCoordinator.java:321)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
Caused by: org.gradle.api.internal.catalog.GeneratedClassCompilationException: Unable to compile generated sources:
- File RootProjectAccessor.java, line: 29, method getGradleVersionsPlugin() is already defined in class org.gradle.accessors.dm.RootProjectAccessor
at org.gradle.api.internal.catalog.SimpleGeneratedJavaClassCompiler.throwCompilationError(SimpleGeneratedJavaClassCompiler.java:82)
at org.gradle.api.internal.catalog.SimpleGeneratedJavaClassCompiler.compile(SimpleGeneratedJavaClassCompiler.java:67)
at org.gradle.api.internal.catalog.DefaultDependenciesAccessors$AbstractAccessorUnitOfWork.execute(DefaultDependenciesAccessors.java:367)
at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:105)
at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:44)
at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:59)
at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:56)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:56)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:44)
at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:42)
at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:75)
at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
at org.gradle.internal.execution.steps.PreCreateOutputParentsStep.execute(PreCreateOutputParentsStep.java:50)
at org.gradle.internal.execution.steps.PreCreateOutputParentsStep.execute(PreCreateOutputParentsStep.java:28)
at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:61)
at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:26)
at org.gradle.internal.execution.steps.NoInputChangesStep.execute(NoInputChangesStep.java:30)
at org.gradle.internal.execution.steps.NoInputChangesStep.execute(NoInputChangesStep.java:21)
at org.gradle.internal.execution.steps.CaptureOutputsAfterExecutionStep.execute(CaptureOutputsAfterExecutionStep.java:69)
at org.gradle.internal.execution.steps.CaptureOutputsAfterExecutionStep.execute(CaptureOutputsAfterExecutionStep.java:46)
at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:189)
at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$1(BuildCacheStep.java:75)
at org.gradle.internal.Either$Right.fold(Either.java:176)
at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:62)
at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:73)
at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:48)
at org.gradle.internal.execution.steps.NeverUpToDateStep.execute(NeverUpToDateStep.java:34)
at org.gradle.internal.execution.steps.NeverUpToDateStep.execute(NeverUpToDateStep.java:22)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
at org.gradle.internal.execution.steps.ResolveNonIncrementalCachingStateStep.executeDelegate(ResolveNonIncrementalCachingStateStep.java:50)
at org.gradle.internal.execution.steps.AbstractResolveCachingStateStep.execute(AbstractResolveCachingStateStep.java:71)
at org.gradle.internal.execution.steps.AbstractResolveCachingStateStep.execute(AbstractResolveCachingStateStep.java:39)
at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:62)
at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:40)
at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:76)
at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:45)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
at org.gradle.internal.execution.steps.AssignImmutableWorkspaceStep.lambda$executeInTemporaryWorkspace$2(AssignImmutableWorkspaceStep.java:188)
at org.gradle.internal.execution.workspace.impl.CacheBasedImmutableWorkspaceProvider$1.withTemporaryWorkspace(CacheBasedImmutableWorkspaceProvider.java:116)
at org.gradle.internal.execution.steps.AssignImmutableWorkspaceStep.executeInTemporaryWorkspace(AssignImmutableWorkspaceStep.java:178)
at org.gradle.internal.execution.steps.AssignImmutableWorkspaceStep.lambda$execute$0(AssignImmutableWorkspaceStep.java:119)
at org.gradle.internal.execution.steps.AssignImmutableWorkspaceStep.execute(AssignImmutableWorkspaceStep.java:119)
at org.gradle.internal.execution.steps.AssignImmutableWorkspaceStep.execute(AssignImmutableWorkspaceStep.java:88)
at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:38)
at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:23)
at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.lambda$execute$2(ExecuteWorkBuildOperationFiringStep.java:67)
at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:67)
at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:39)
at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:46)
at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:34)
at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:47)
at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:34)
at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:64)
at org.gradle.api.internal.catalog.DefaultDependenciesAccessors.executeWork(DefaultDependenciesAccessors.java:190)
at org.gradle.api.internal.catalog.DefaultDependenciesAccessors.writeProjectAccessors(DefaultDependenciesAccessors.java:175)
at org.gradle.api.internal.catalog.DefaultDependenciesAccessors.generateAccessors(DefaultDependenciesAccessors.java:159)
... 153 more
BUILD FAILED in 549ms
Thanks @ShadowRZ. You shouldn't need to attach this plugin as a composite build, etc. The source code should be published with the artifact so you can step through it and your IDE will resolve. You can just run the task in debug mode and see what is adding to the configuration set dynamically. The PiTest example shows it adding a new configuration when the testImplementation configuration is resolved, but since Gradle does that lazily when needed their addition happens at execution time when materializing it via the DefaultDomainObjectCollection iterator. Since its lazy rather than eager at configuration time, this is a breaking usage of the Gradle APIs that has been incorrect for a number of major releases but the latest release is more aggressive after the grace period. Whatever plugins you're using which are corrupting the Gradle state needs to be found and fixed because they break the API contract. Most plugins don't need to iterate over the configurations, but those like this one or dependency-check which looks for CVEs will break.
@ben-manes Ah, good to know. Also because I can't reproduce this problem when running the task with IDE, I instead used the CLI with -Dorg.gradle.debug=true --no-daemon --no-parallel --no-configuration-cache and create a remove JVM debug run configuration in Android Studio.
Narrowing down to the module that hit the error (my project is using multi module setup), I moved the apply of this plugin to the module's build.gradle.kts. When the ConcurrentModificationException was hit, it was processing debugAndroidTestCompileClasspath configuration, and I got the following stacktrace before the exception trace:
isProperUsage:1273, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
warnOrFailOnInvalidUsage:1301, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
warnOrFailOnInvalidUsage:1297, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
getResolvedConfiguration:553, DefaultConfiguration (org.gradle.api.internal.artifacts.configurations)
getResolvedConfiguration:-1, DefaultLegacyConfiguration_Decorated (org.gradle.api.internal.artifacts.configurations)
getCurrentCoordinates:279, Resolver (com.github.benmanes.gradle.versions.updates)
resolve:56, Resolver (com.github.benmanes.gradle.versions.updates)
resolve:95, DependencyUpdates (com.github.benmanes.gradle.versions.updates)
lambda 'forEach' in 'resolveProjects':80, DependencyUpdates (com.github.benmanes.gradle.versions.updates)
forEach:215, DependencyUpdates (com.github.benmanes.gradle.versions.updates)
resolveProjects:76, DependencyUpdates (com.github.benmanes.gradle.versions.updates)
run:46, DependencyUpdates (com.github.benmanes.gradle.versions.updates)
dependencyUpdates:140, DependencyUpdatesTask (com.github.benmanes.gradle.versions.updates)
invokeSpecial:-1, DirectMethodHandle$Holder (java.lang.invoke)
invoke:-1, LambdaForm$MH/0x0000000100318800 (java.lang.invoke)
invokeExact_MT:-1, Invokers$Holder (java.lang.invoke)
invokeImpl:-1, DirectMethodHandleAccessor (jdk.internal.reflect)
invoke:-1, DirectMethodHandleAccessor (jdk.internal.reflect)
invoke:-1, Method (java.lang.reflect)
invoke:125, JavaMethod (org.gradle.internal.reflect)
doExecute:58, StandardTaskAction (org.gradle.api.internal.project.taskfactory)
execute:51, StandardTaskAction (org.gradle.api.internal.project.taskfactory)
execute:29, StandardTaskAction (org.gradle.api.internal.project.taskfactory)
run:252, TaskExecution$3 (org.gradle.api.internal.tasks.execution)
execute:29, DefaultBuildOperationRunner$1 (org.gradle.internal.operations)
execute:26, DefaultBuildOperationRunner$1 (org.gradle.internal.operations)
execute:66, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:166, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner (org.gradle.internal.operations)
run:47, DefaultBuildOperationRunner (org.gradle.internal.operations)
executeAction:237, TaskExecution (org.gradle.api.internal.tasks.execution)
executeActions:220, TaskExecution (org.gradle.api.internal.tasks.execution)
executeWithPreviousOutputFiles:203, TaskExecution (org.gradle.api.internal.tasks.execution)
execute:170, TaskExecution (org.gradle.api.internal.tasks.execution)
executeInternal:105, ExecuteStep (org.gradle.internal.execution.steps)
access$000:44, ExecuteStep (org.gradle.internal.execution.steps)
call:59, ExecuteStep$1 (org.gradle.internal.execution.steps)
call:56, ExecuteStep$1 (org.gradle.internal.execution.steps)
execute:209, DefaultBuildOperationRunner$CallableBuildOperationWorker (org.gradle.internal.operations)
execute:204, DefaultBuildOperationRunner$CallableBuildOperationWorker (org.gradle.internal.operations)
execute:66, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:166, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner (org.gradle.internal.operations)
call:53, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:56, ExecuteStep (org.gradle.internal.execution.steps)
execute:44, ExecuteStep (org.gradle.internal.execution.steps)
execute:42, CancelExecutionStep (org.gradle.internal.execution.steps)
executeWithoutTimeout:75, TimeoutStep (org.gradle.internal.execution.steps)
execute:55, TimeoutStep (org.gradle.internal.execution.steps)
execute:50, PreCreateOutputParentsStep (org.gradle.internal.execution.steps)
execute:28, PreCreateOutputParentsStep (org.gradle.internal.execution.steps)
execute:68, RemovePreviousOutputsStep (org.gradle.internal.execution.steps)
execute:38, RemovePreviousOutputsStep (org.gradle.internal.execution.steps)
execute:61, BroadcastChangingOutputsStep (org.gradle.internal.execution.steps)
execute:26, BroadcastChangingOutputsStep (org.gradle.internal.execution.steps)
execute:69, CaptureOutputsAfterExecutionStep (org.gradle.internal.execution.steps)
execute:46, CaptureOutputsAfterExecutionStep (org.gradle.internal.execution.steps)
execute:39, ResolveInputChangesStep (org.gradle.internal.execution.steps)
execute:28, ResolveInputChangesStep (org.gradle.internal.execution.steps)
executeWithoutCache:189, BuildCacheStep (org.gradle.internal.execution.steps)
lambda$execute$1:75, BuildCacheStep (org.gradle.internal.execution.steps)
apply:-1, BuildCacheStep$$Lambda/0x0000000100cd84b8 (org.gradle.internal.execution.steps)
fold:176, Either$Right (org.gradle.internal)
fold:62, CachingState (org.gradle.internal.execution.caching)
execute:73, BuildCacheStep (org.gradle.internal.execution.steps)
execute:48, BuildCacheStep (org.gradle.internal.execution.steps)
execute:46, StoreExecutionStateStep (org.gradle.internal.execution.steps)
execute:35, StoreExecutionStateStep (org.gradle.internal.execution.steps)
executeBecause:75, SkipUpToDateStep (org.gradle.internal.execution.steps)
lambda$execute$2:53, SkipUpToDateStep (org.gradle.internal.execution.steps)
get:-1, SkipUpToDateStep$$Lambda/0x0000000100cd26e8 (org.gradle.internal.execution.steps)
orElseGet:-1, Optional (java.util)
execute:53, SkipUpToDateStep (org.gradle.internal.execution.steps)
execute:35, SkipUpToDateStep (org.gradle.internal.execution.steps)
execute:37, MarkSnapshottingInputsFinishedStep (org.gradle.internal.execution.steps.legacy)
execute:27, MarkSnapshottingInputsFinishedStep (org.gradle.internal.execution.steps.legacy)
executeDelegate:49, ResolveIncrementalCachingStateStep (org.gradle.internal.execution.steps)
executeDelegate:27, ResolveIncrementalCachingStateStep (org.gradle.internal.execution.steps)
execute:71, AbstractResolveCachingStateStep (org.gradle.internal.execution.steps)
execute:39, AbstractResolveCachingStateStep (org.gradle.internal.execution.steps)
execute:64, ResolveChangesStep (org.gradle.internal.execution.steps)
execute:35, ResolveChangesStep (org.gradle.internal.execution.steps)
execute:62, ValidateStep (org.gradle.internal.execution.steps)
execute:40, ValidateStep (org.gradle.internal.execution.steps)
execute:76, AbstractCaptureStateBeforeExecutionStep (org.gradle.internal.execution.steps)
execute:45, AbstractCaptureStateBeforeExecutionStep (org.gradle.internal.execution.steps)
executeWithNonEmptySources:136, AbstractSkipEmptyWorkStep (org.gradle.internal.execution.steps)
execute:61, AbstractSkipEmptyWorkStep (org.gradle.internal.execution.steps)
execute:38, AbstractSkipEmptyWorkStep (org.gradle.internal.execution.steps)
execute:38, MarkSnapshottingInputsStartedStep (org.gradle.internal.execution.steps.legacy)
execute:36, LoadPreviousExecutionStateStep (org.gradle.internal.execution.steps)
execute:23, LoadPreviousExecutionStateStep (org.gradle.internal.execution.steps)
execute:75, HandleStaleOutputsStep (org.gradle.internal.execution.steps)
execute:41, HandleStaleOutputsStep (org.gradle.internal.execution.steps)
lambda$execute$0:35, AssignMutableWorkspaceStep (org.gradle.internal.execution.steps)
executeInWorkspace:-1, AssignMutableWorkspaceStep$$Lambda/0x0000000100cbe428 (org.gradle.internal.execution.steps)
withWorkspace:297, TaskExecution$4 (org.gradle.api.internal.tasks.execution)
execute:31, AssignMutableWorkspaceStep (org.gradle.internal.execution.steps)
execute:22, AssignMutableWorkspaceStep (org.gradle.internal.execution.steps)
execute:40, ChoosePipelineStep (org.gradle.internal.execution.steps)
execute:23, ChoosePipelineStep (org.gradle.internal.execution.steps)
lambda$execute$2:67, ExecuteWorkBuildOperationFiringStep (org.gradle.internal.execution.steps)
get:-1, ExecuteWorkBuildOperationFiringStep$$Lambda/0x00000001006b9058 (org.gradle.internal.execution.steps)
orElseGet:-1, Optional (java.util)
execute:67, ExecuteWorkBuildOperationFiringStep (org.gradle.internal.execution.steps)
execute:39, ExecuteWorkBuildOperationFiringStep (org.gradle.internal.execution.steps)
execute:46, IdentityCacheStep (org.gradle.internal.execution.steps)
execute:34, IdentityCacheStep (org.gradle.internal.execution.steps)
execute:47, IdentifyStep (org.gradle.internal.execution.steps)
execute:34, IdentifyStep (org.gradle.internal.execution.steps)
execute:64, DefaultExecutionEngine$1 (org.gradle.internal.execution.impl)
executeIfValid:132, ExecuteActionsTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:121, ExecuteActionsTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:41, ProblemsTaskPathTrackingTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:46, FinalizePropertiesTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:51, ResolveTaskExecutionModeExecuter (org.gradle.api.internal.tasks.execution)
execute:57, SkipTaskWithNoActionsExecuter (org.gradle.api.internal.tasks.execution)
execute:74, SkipOnlyIfTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:36, CatchExceptionTaskExecuter (org.gradle.api.internal.tasks.execution)
executeTask:77, EventFiringTaskExecuter$1 (org.gradle.api.internal.tasks.execution)
call:55, EventFiringTaskExecuter$1 (org.gradle.api.internal.tasks.execution)
call:52, EventFiringTaskExecuter$1 (org.gradle.api.internal.tasks.execution)
execute:209, DefaultBuildOperationRunner$CallableBuildOperationWorker (org.gradle.internal.operations)
execute:204, DefaultBuildOperationRunner$CallableBuildOperationWorker (org.gradle.internal.operations)
execute:66, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner$2 (org.gradle.internal.operations)
execute:166, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:59, DefaultBuildOperationRunner (org.gradle.internal.operations)
call:53, DefaultBuildOperationRunner (org.gradle.internal.operations)
execute:52, EventFiringTaskExecuter (org.gradle.api.internal.tasks.execution)
execute:45, LocalTaskNodeExecutor (org.gradle.execution.plan)
execute:347, DefaultTaskExecutionGraph$InvokeNodeExecutorsAction (org.gradle.execution.taskgraph)
execute:334, DefaultTaskExecutionGraph$InvokeNodeExecutorsAction (org.gradle.execution.taskgraph)
lambda$execute$0:330, DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction (org.gradle.execution.taskgraph)
run:-1, DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction$$Lambda/0x0000000100c978e8 (org.gradle.execution.taskgraph)
with:84, CurrentBuildOperationRef (org.gradle.internal.operations)
execute:330, DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction (org.gradle.execution.taskgraph)
execute:319, DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction (org.gradle.execution.taskgraph)
execute:459, DefaultPlanExecutor$ExecutorWorker (org.gradle.execution.plan)
run:376, DefaultPlanExecutor$ExecutorWorker (org.gradle.execution.plan)
onExecute:64, ExecutorPolicy$CatchAndRecordFailures (org.gradle.internal.concurrent)
run:47, AbstractManagedExecutor$1 (org.gradle.internal.concurrent)
runWorker:-1, ThreadPoolExecutor (java.util.concurrent)
run:-1, ThreadPoolExecutor$Worker (java.util.concurrent)
runWith:-1, Thread (java.lang)
run:-1, Thread (java.lang)
That project's build.gradle.kts looks like this:
plugins {
id("io.github.shadowrz.projectkafka.library")
id("com.github.ben-manes.versions") version "0.52.0"
}
android {
namespace = "io.github.shadowrz.projectkafka.libraries.deeplink"
}
where the io.github.shadowrz.projectkakfa.library convention plugin is defined to only include com.android.library and org.jetbrains.kotlin.android plugins and configure them.
Furthermore, AGP 8.12.1 is the first version of the plugin that would reproduce this problem, downgrading AGP (without affecting other plugins' versions) to 8.12.0 will allow dependencyUpdates task to succeed.
Additionally, it will only throw ConcurrentModificationException in a library module (applies com.android.library), not in a app (applies com.android.application).
Tested in a minimal Android Library module project too.
It looks like fetching the android gradle plugin is a large undertaking. Its not available for simple browsing and requires downloading the universe to get something to look at. The browsable code seems to be many years out of date.
Presumably they are changing state but its going to be a while before it syncs locally for me to skim their code. I am not an android developer so it is foreign to me.
@jvandort has been extraordinarily helpful and generous with his advice, so he might have some pointers.
No luck with AGP 8.13.0
@ben-manes Is it possible to use the published source artifacts of AGP on Google Maven repo as a reference source?
It should be at https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/8.12.1/gradle-8.12.1-sources.jar and https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/8.12.1/gradle-api-8.12.1-sources.jar
Thanks. That is quite a lot of code! I tried skimming it but it was not easy to navigate. A few possibilities,
SourceSetManagerwill create configurations for a sourceSet. Since Gradle now prefers to register sourceSets lazily, maybe when it has to materialize that then there are some weird interactions.- There is a lot of complexity in variant building. I am not very familiar with that concept but it seems messy.
The easiest would be if Gradle switched to a concurrent collection to avoid the fail fast iterator. I suspect they'd frown on that as a plugin misuse that should be fixed, but this is a bit beyond me as well.
It looks like fetching the android gradle plugin is a large undertaking. Its not available for simple browsing and requires downloading the universe to get something to look at. The browsable code seems to be many years out of date.
Presumably they are changing state but its going to be a while before it syncs locally for me to skim their code. I am not an android developer so it is foreign to me.
@jvandort has been extraordinarily helpful and generous with his advice, so he might have some pointers.
This is an old branch. The right branch is studio-main
@ben-manes You might also want to refer to AGP 8.12.0 source code too, located in Google Maven repo at https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/8.12.0/gradle-8.12.0-sources.jar and https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/8.12.0/gradle-api-8.12.0-sources.jar
Diffing 8.12.0 and 8.12.1 code should give you an insight on what changed between these two versions.