Skip to content

Configuration cache store fails in multi-project builds: metadata repository URI is resolved via a detached configuration during CC serialization (also blocks Isolated Projects) #1013

Description

@vjovanov

Symptom

In multi-project builds with the configuration cache enabled and the reachability metadata repository active (the default), storing the configuration cache entry can fail with:

Configuration cache state could not be cached: field `__uri__` of
`org.graalvm.buildtools.gradle.internal.GraalVMReachabilityMetadataService$Params_Decorated`
bean found in Gradle runtime: error writing value of type 'org.gradle.api.internal.provider.DefaultProperty'
> Resolution of the configuration ':<project>:detachedConfiguration2' was attempted without an exclusive lock.
  This is unsafe and not allowed.

The same wiring is also a blocker for Isolated Projects, which the plugin currently does not support at all.

Root cause

The GraalVMReachabilityMetadataService build service declares a Property<URI> parameter (GraalVMReachabilityMetadataService.java#L99).

That parameter is wired to a provider whose transformer calls computeMetadataRepositoryUri (NativeImagePlugin.java#L630). When the user has not configured an explicit metadataRepository.uri, that method:

  1. creates a detached configuration and adds org.graalvm.buildtools:graalvm-reachability-metadata:<version>:repository@zip to it (NativeImagePlugin.java#L679),
  2. resolves it eagerly via getIncoming().artifactView(...).getFiles().getFiles() to obtain a local file URI, falling back to the GitHub release URL if resolution yields nothing.

Build-service parameters are finalized when the configuration cache entry is stored, so this dependency resolution runs from inside configuration-cache serialization — outside any proper resolution context. In a multi-project build this trips Gradle's project-lock check ("resolution … attempted without an exclusive lock"). Additionally, the transformer lambda captures the live Project instance, which is incompatible with Isolated Projects by construction.

This is consistent with a gap in our own test coverage: the configuration-cache functional tests either run single-project builds or explicitly disable the metadata repository (e.g. LayeredApplicationFunctionalTest.groovy#L71) — precisely the component this error comes from.

Workarounds

Until this is fixed, affected users can either:

  • set the repository URI explicitly, which skips the detached-configuration resolution:

    graalvmNative {
        metadataRepository {
            uri("https://github.com/oracle/graalvm-reachability-metadata/releases/download/<version>/graalvm-reachability-metadata-<version>.zip")
        }
    }
  • or disable the metadata repository (graalvmNative.metadataRepository.enabled = false) if it is not needed.

Proposed fix

Replace the detached configuration resolved at serialization time with a named, resolvable configuration created at plugin-apply time, carrying the repository zip as a regular dependency. The build-service uri parameter should then be derived from that configuration's incoming artifacts (lazily, via ArtifactCollection/FileCollection providers), so that:

  • resolution participates in normal dependency resolution with correct locking,
  • the provider no longer captures Project,
  • the download/extraction currently happening in the service constructor (GraalVMReachabilityMetadataService.java#L106-L113) can happen at execution time.

This would fix the configuration-cache failure in multi-project builds and is a prerequisite for Isolated Projects support, which should be tracked (and eventually tested in the configCacheFunctionalTest matrix) as a follow-up.

Environment

  • Reported with the reachability metadata repository enabled (default) in a multi-project build.
  • The plugin's general configuration-cache support (serializable lambdas, per-project build services, configCacheFunctionalTest CI job) is otherwise in place; this issue is specific to the metadata-repository URI wiring.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions