Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Disallow BuildServices to be used as inputs to ValueSources obtained at configuration time #22337

Description

@mlopatkin

A ValueSource can take parameters in the form of Properties. A BuildService is obtained as a Provider. This Provider can be wired to the input Property of the ValueSource. It works well without the configuration cache. However, when the configuration cache is enabled and the ValueSource is obtained at the configuration time, things go wrong. The cache cannot be reused, as the fingerprinting routine cannot restore the BuildService; the build fails with a cryptic exception.

Expected Behavior

Either of two options are expected:

  1. If Gradle is not going to support this use case: provide an error with a clear message that this use is unsupported, preferably when storing the cache
  2. Otherwise, this should just work, and the service instance should be available for the ValueSource computation.

Current Behavior

The build fails when trying to check the cache validity:

org.gradle.api.GradleException: Could not load the value of field `__service__` of `ServiceValueSource$Params` bean found in field `parameters` of `org.gradle.api.internal.provider.DefaultValueSourceProviderFactory$DefaultObtainedValue` bean found in field `obtainedValue` of `org.gradle.configurationcache.fingerprint.ConfigurationCacheFingerprint$ValueSource` bean found in Gradle runtime.
  	at org.gradle.configurationcache.serialization.beans.BeanPropertyReaderKt.readPropertyValue(BeanPropertyReader.kt:108)
  	at org.gradle.configurationcache.serialization.beans.BeanPropertyReader.readStateOf(BeanPropertyReader.kt:67)
  	at org.gradle.configurationcache.serialization.codecs.BeanCodec.readBeanOf(BeanCodec.kt:72)
  	at org.gradle.configurationcache.serialization.codecs.BeanCodec.decode(BeanCodec.kt:47)
  	at org.gradle.configurationcache.serialization.CombinatorsKt$reentrant$1$decodeLoop$1.invokeSuspend(Combinators.kt:165)
  	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
  	at kotlin.coroutines.ContinuationKt.startCoroutine(Continuation.kt:115)
  	at org.gradle.configurationcache.serialization.CombinatorsKt$reentrant$1.decodeLoop(Combinators.kt:166)
  	at org.gradle.configurationcache.serialization.CombinatorsKt$reentrant$1.decode(Combinators.kt:130)
  	at org.gradle.configurationcache.serialization.codecs.BindingsBackedCodec.decode(BindingsBackedCodec.kt:59)
  	at org.gradle.configurationcache.serialization.DefaultReadContext.read(Contexts.kt:259)
  	at org.gradle.configurationcache.fingerprint.ConfigurationCacheFingerprintChecker.checkBuildScopedFingerprint(ConfigurationCacheFingerprintChecker.kt:58)
  	at org.gradle.configurationcache.fingerprint.ConfigurationCacheFingerprintController.checkBuildScopedFingerprint(ConfigurationCacheFingerprintController.kt:243)
  	at org.gradle.configurationcache.DefaultConfigurationCache$checkBuildScopedFingerprint$1.invokeSuspend(DefaultConfigurationCache.kt:461)
  	at org.gradle.configurationcache.DefaultConfigurationCache$readFingerprintFile$1$1.invokeSuspend(DefaultConfigurationCache.kt:480)
  	at org.gradle.configurationcache.ConfigurationCacheIO$withReadContextFor$1$1$1$1.invokeSuspend(ConfigurationCacheIO.kt:248)
  	at org.gradle.configurationcache.serialization.RunningKt$runReadOperation$2.invokeSuspend(Running.kt:34)
  	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
  	at kotlin.coroutines.ContinuationKt.startCoroutine(Continuation.kt:115)
  	at org.gradle.configurationcache.serialization.RunningKt.runToCompletion(Running.kt:56)
  	at org.gradle.configurationcache.serialization.RunningKt.runReadOperation(Running.kt:33)
  	at org.gradle.configurationcache.ConfigurationCacheIO.withReadContextFor$configuration_cache(ConfigurationCacheIO.kt:247)
  	at org.gradle.configurationcache.DefaultConfigurationCache.readFingerprintFile(DefaultConfigurationCache.kt:478)
  	at org.gradle.configurationcache.DefaultConfigurationCache.checkBuildScopedFingerprint(DefaultConfigurationCache.kt:459)
  	at org.gradle.configurationcache.DefaultConfigurationCache.checkFingerprintAgainstLoadedProperties(DefaultConfigurationCache.kt:441)
  	at org.gradle.configurationcache.DefaultConfigurationCache.checkFingerprint(DefaultConfigurationCache.kt:429)
  	at org.gradle.configurationcache.DefaultConfigurationCache.access$checkFingerprint(DefaultConfigurationCache.kt:53)
  	at org.gradle.configurationcache.DefaultConfigurationCache$checkFingerprint$1.invoke(DefaultConfigurationCache.kt:278)
  	at org.gradle.configurationcache.DefaultConfigurationCache$checkFingerprint$1.invoke(DefaultConfigurationCache.kt:271)
  	at org.gradle.configurationcache.ConfigurationCacheRepository$StoreImpl$useForStateLoad$2.invoke(ConfigurationCacheRepository.kt:164)
  	at org.gradle.configurationcache.ConfigurationCacheRepository$StoreImpl$useForStateLoad$2.invoke(ConfigurationCacheRepository.kt:163)
  	at org.gradle.configurationcache.ConfigurationCacheRepository$withExclusiveAccessToCache$1.create(ConfigurationCacheRepository.kt:244)
  	at org.gradle.cache.internal.LockOnDemandCrossProcessCacheAccess.withFileLock(LockOnDemandCrossProcessCacheAccess.java:90)
  	at org.gradle.cache.internal.DefaultCacheAccess.withFileLock(DefaultCacheAccess.java:191)
  	at org.gradle.cache.internal.DefaultPersistentDirectoryStore.withFileLock(DefaultPersistentDirectoryStore.java:188)
  	at org.gradle.cache.internal.DefaultCacheFactory$ReferenceTrackingCache.withFileLock(DefaultCacheFactory.java:209)
  	at org.gradle.configurationcache.ConfigurationCacheRepository.withExclusiveAccessToCache(ConfigurationCacheRepository.kt:242)
  	at org.gradle.configurationcache.ConfigurationCacheRepository.access$withExclusiveAccessToCache(ConfigurationCacheRepository.kt:46)
  	at org.gradle.configurationcache.ConfigurationCacheRepository$StoreImpl.useForStateLoad(ConfigurationCacheRepository.kt:163)
  	at org.gradle.configurationcache.DefaultConfigurationCache.checkFingerprint(DefaultConfigurationCache.kt:271)
  	at org.gradle.configurationcache.DefaultConfigurationCache.determineCacheAction(DefaultConfigurationCache.kt:221)
  	at org.gradle.configurationcache.DefaultConfigurationCache.initializeCacheEntry(DefaultConfigurationCache.kt:114)
  	at org.gradle.configurationcache.ConfigurationCacheBuildTreeLifecycleControllerFactory.createRootBuildController(ConfigurationCacheBuildTreeLifecycleControllerFactory.kt:54)
  	at org.gradle.composite.internal.DefaultRootBuildState.<init>(DefaultRootBuildState.java:73)
  	at org.gradle.composite.internal.BuildStateFactory.createRootBuild(BuildStateFactory.java:66)
  	at org.gradle.composite.internal.DefaultIncludedBuildRegistry.createRootBuild(DefaultIncludedBuildRegistry.java:91)
...
Caused by: java.lang.IllegalArgumentException: Could not find build ':'
  	at org.gradle.composite.internal.DefaultIncludedBuildRegistry.getBuild(DefaultIncludedBuildRegistry.java:147)
  	at org.gradle.configurationcache.serialization.codecs.BuildServiceProviderCodec.buildServiceRegistryOf(ProviderCodecs.kt:188)
  	at org.gradle.configurationcache.serialization.codecs.BuildServiceProviderCodec.decode(ProviderCodecs.kt:183)
  	at org.gradle.configurationcache.serialization.codecs.BindingsBackedCodec.decode(BindingsBackedCodec.kt:59)
  	at org.gradle.configurationcache.serialization.codecs.FixedValueReplacingProviderCodec.decodeValue(ProviderCodecs.kt:134)
  	at org.gradle.configurationcache.serialization.codecs.FixedValueReplacingProviderCodec.decodeProvider(ProviderCodecs.kt:116)
  	at org.gradle.configurationcache.serialization.codecs.PropertyCodec.decode(ProviderCodecs.kt:269)
  	at org.gradle.configurationcache.serialization.codecs.BindingsBackedCodec.decode(BindingsBackedCodec.kt:59)
  	at org.gradle.configurationcache.serialization.DefaultReadContext.read(Contexts.kt:259)
  	at org.gradle.configurationcache.serialization.beans.BeanPropertyReaderKt.readPropertyValue(BeanPropertyReader.kt:102)

Context

My goal was to invalidate the configuration cache with the value obtained through the BuildService (with a side effect): the service is starting a web server on a random port, the URL of the server is used to configure some tasks. The build service then stops the server when closed.

The use case is not very compelling, as the lifecycle of the service is unclear in case the cache is actually invalidated - is the service used at fingerprint check time going to be discarded?

Steps to Reproduce

See #22338.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions