gradle / gradle

Adaptable, fast automation for all
https://gradle.org
Apache License 2.0
16.86k stars 4.72k forks source link

CC error reading `ValueSource` shared across projects #31111

Open bamboo opened 17 hours ago

bamboo commented 17 hours ago

Initially reported in the androidx build:

> Configure project :annotation:annotation
w: New 'wasm' target is Work-in-Progress and is subject to change without notice. Please report encountered issues to https://kotl.in/issue

Exception in thread "DefaultSharedObjectDecoder reader thread" org.gradle.api.GradleException: Could not load the value of field `elements` of `org.gradle.internal.serialize.codecs.core.ResolutionBackedFileCollectionSpec` bean found in field `__desugarJson__` of `com.android.build.gradle.internal.utils.DesugarConfigJson$Parameters` bean found in Gradle runtime.
        at org.gradle.internal.serialize.graph.BeanPropertyExtensionsKt.readPropertyValue(BeanPropertyExtensions.kt:70)
        at org.gradle.internal.serialize.graph.BeanPropertyExtensionsKt$readPropertyValue$1.invokeSuspend(BeanPropertyExtensions.kt)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlin.coroutines.SafeContinuation.resumeWith(SafeContinuationJvm.kt:41)
        at org.gradle.internal.serialize.graph.CombinatorsKt$reentrant$1$decodeLoop$$inlined$Continuation$1.resumeWith(Continuation.kt:78)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
        at kotlin.coroutines.ContinuationKt.startCoroutine(Continuation.kt:115)
        at org.gradle.internal.serialize.graph.CombinatorsKt$reentrant$1.decodeLoop(Combinators.kt:123)
        at org.gradle.internal.serialize.graph.CombinatorsKt$reentrant$1.decode(Combinators.kt:85)
        at org.gradle.internal.serialize.graph.codecs.BindingsBackedCodec.decode(BindingsBackedCodec.kt:70)
        at org.gradle.internal.serialize.graph.DefaultReadContext.read(Contexts.kt:264)
        at org.gradle.internal.serialize.codecs.core.ValueSourceProviderCodec.decodeValueSource(ProviderCodecs.kt:335)
        at org.gradle.internal.serialize.codecs.core.ValueSourceProviderCodec.access$decodeValueSource(ProviderCodecs.kt:282)
        at org.gradle.internal.serialize.codecs.core.ValueSourceProviderCodec$decode$2.invokeSuspend(ProviderCodecs.kt:307)
        at org.gradle.internal.serialize.codecs.core.ValueSourceProviderCodec$decode$2.invoke(ProviderCodecs.kt)
        at org.gradle.internal.serialize.codecs.core.ValueSourceProviderCodec$decode$2.invoke(ProviderCodecs.kt)
        at org.gradle.internal.serialize.graph.InlineSharedObjectDecoder.read(Contexts.kt:194)
        at org.gradle.internal.serialize.graph.DefaultReadContext.readSharedObject(Contexts.kt:269)
        at org.gradle.internal.serialize.codecs.core.ValueSourceProviderCodec.decode(ProviderCodecs.kt:305)
        at org.gradle.internal.serialize.graph.codecs.BindingsBackedCodec.decode(BindingsBackedCodec.kt:70)
        at org.gradle.internal.serialize.codecs.core.FixedValueReplacingProviderCodec.decodeValue(ProviderCodecs.kt:145)
        at org.gradle.internal.serialize.codecs.core.FixedValueReplacingProviderCodec.decodeProvider(ProviderCodecs.kt:131)
        at org.gradle.internal.serialize.codecs.core.ProviderCodec.decode(ProviderCodecs.kt:223)
        at org.gradle.internal.serialize.graph.codecs.BindingsBackedCodec.decode(BindingsBackedCodec.kt:70)
        at org.gradle.internal.serialize.graph.DefaultReadContext.read(Contexts.kt:264)
        at org.gradle.internal.cc.impl.serialize.DefaultSharedObjectDecoder$reader$1$2$read$1.invokeSuspend(DefaultGlobalValueCodec.kt:138)
        at org.gradle.internal.cc.impl.serialize.DefaultSharedObjectDecoder$reader$1$2$read$1.invoke(DefaultGlobalValueCodec.kt)
        at org.gradle.internal.cc.impl.serialize.DefaultSharedObjectDecoder$reader$1$2$read$1.invoke(DefaultGlobalValueCodec.kt)
        at org.gradle.internal.serialize.graph.RunningKt$runReadOperation$2.invokeSuspend(Running.kt:33)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlin.coroutines.ContinuationKt.startCoroutine(Continuation.kt:115)
        at org.gradle.internal.serialize.graph.RunningKt.runToCompletion(Running.kt:54)
        at org.gradle.internal.serialize.graph.RunningKt.runReadOperation(Running.kt:32)
        at org.gradle.internal.cc.impl.serialize.DefaultSharedObjectDecoder$reader$1.invoke(DefaultGlobalValueCodec.kt:137)
        at org.gradle.internal.cc.impl.serialize.DefaultSharedObjectDecoder$reader$1.invoke(DefaultGlobalValueCodec.kt:126)
        at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)
Caused by: java.lang.IllegalStateException: Project ':room:integration-tests:room-testapp' should be in state Created or later.
        at org.gradle.internal.model.StateTransitionController.assertInStateOrLater(StateTransitionController.java:67)
        at org.gradle.api.internal.project.ProjectLifecycleController.getMutableModel(ProjectLifecycleController.java:80)
        at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.getMutableModel(DefaultProjectStateRegistry.java:375)
        at org.gradle.internal.cc.base.serialize.ProjectProviderKt.getProject(ProjectProvider.kt:27)
        at org.gradle.internal.serialize.codecs.dm.transform.TransformStepCodec.decode(TransformStepCodec.kt:49)
        at org.gradle.internal.serialize.graph.codecs.BindingsBackedCodec.decode(BindingsBackedCodec.kt:70)
        at org.gradle.internal.serialize.graph.DefaultReadContext.read(Contexts.kt:264)
        at org.gradle.internal.serialize.graph.CodecKt.readNonNull(Codec.kt:156)
        at org.gradle.internal.serialize.codecs.dm.transform.TransformStepSpecCodec.decode(Transforms.kt:66)
        at org.gradle.internal.serialize.graph.codecs.BindingsBackedCodec.decode(BindingsBackedCodec.kt:70)
        at org.gradle.internal.serialize.graph.DefaultReadContext.read(Contexts.kt:264)
        at org.gradle.internal.serialize.graph.CombinatorsKt.readList(Combinators.kt:174)
        at org.gradle.internal.serialize.codecs.dm.transform.CalculateArtifactsCodec.decode(CalculateArtifactsCodec.kt:68)
        at org.gradle.internal.serialize.codecs.dm.transform.CalculateArtifactsCodec$decode$1.invokeSuspend(CalculateArtifactsCodec.kt)

The ValueSource in question is setup in DesugarLibUtils.kt#149 with parameters coming from a build service that resolves artifactFiles from a shared Configuration.

bamboo commented 17 hours ago

Related to #31039

mlopatkin commented 16 hours ago

I suspect that some buildscan callback has a valuesource or build service reference and it kicks off the decoder. Then we race. Such callbacks may trigger failures even without deduplication/parallel store if they have project-resolving data captured. See this test, for example (quickly cooked from the build service test of the linked issue):

    def "foobar"() {
        settingsFile """
            include("producer")
            include("consumer")
        """
        buildFile file("producer/build.gradle"), '''
            apply plugin: 'base'
            configurations {
                'default' {
                    attributes {
                        attribute(Attribute.of('color', String), 'red')
                    }
                }
            }
            artifacts {
                'default' file('file.txt')
            }
            tasks.register('ok') {
                doLast {
                    println("Making sure this project is considered relevant")
                }
            }
        '''
        file("producer/file.txt").createFile()
        buildFile file("consumer/build.gradle"), """
            apply plugin: 'base'
            ${withIdentityTransformSource()}
            configurations {
                implementation
            }
            def color = Attribute.of('color', String)
            dependencies {
                registerTransform(IdentityTransform) {
                    from.attribute(color, 'red')
                    to.attribute(color, 'blue')
                }
                implementation(project(":producer"))
            }
            abstract class ValueTask extends DefaultTask {
                @TaskAction def doIt() {
                    println("value: " + System.properties["some.property"].get())
                }
            }
            abstract class FilesValueSource implements ValueSource<String, Params> {
                interface Params extends ValueSourceParameters {
                    ConfigurableFileCollection getInFiles()
                }

                String obtain() {
                    return "123"
                }
            }

            def pp = providers.of(FilesValueSource) {
                parameters {
                    inFiles.from(
                        configurations.implementation.incoming.artifactView {
                            attributes { attribute(color, 'blue') }
                        }.files
                    )
                }
            }
            System.properties["some.property"] = pp
            tasks.register('ok', ValueTask) {
                dependsOn(configurations.implementation)
            }
        """

        when:
        configurationCacheRun 'ok'

        then:
        outputContains 'Transforming file.txt'
        outputContains "value: file.txt"

        when:
        configurationCacheRun 'ok'

        then:
        outputDoesNotContain 'Transforming file.txt'
        outputContains "value: file.txt"
    }

    private String withIdentityTransformSource() {
        """
            abstract class IdentityTransform implements ${TransformAction.name}<${TransformParameters.name}.None> {
                @${InputArtifact.name} abstract Provider<FileSystemLocation> getInputArtifact()
                @Override void transform(${TransformOutputs.name} outputs) {
                    println('Transforming ' + inputArtifact.get().asFile.name)
                    outputs.file(inputArtifact)
                }
            }
        """
    }
liutikas commented 14 hours ago

Removing develocity plugin does seem to allow me to configure the project 3 out of 3 tries.

bamboo commented 13 hours ago

See this test, for example (quickly cooked from the build service test of the linked issue):

Hey @mlopatkin, I'm missing the connection to build scans from the test code you posted 🤔

mlopatkin commented 11 hours ago

See this test, for example (quickly cooked from the build service test of the linked issue):

Hey @mlopatkin, I'm missing the connection to build scans from the test code you posted 🤔

We do save build scan callbacks and the modified system properties in the build tree state before restoring the projects Thus, when something that requires a project to load is stored there, it breaks loading even without parallel/dedupe changes, like in 8.10 It also means that loading callbacks or the system property value may kick off background loading of shared objects if these data happen to be a shared object themselves.

I don't see how we can easily solve the original issue, but with some coordination we can ensure that the projects are ready by the time we start reading the stuff that references them.

I can pick this up if you'd like.