I’m trying to understand why attached and detached configurations behave differently when being resolved, more notably the reason for “Project :x declares a dependency from configuration ‘detachedConfiguration1’ to configuration ‘default’ which is not declared in the descriptor for project :x.”
Given the following script and Gradle 5.6.2:
apply plugin: 'java' // which transitively provides the "default" configuration
configurations {
passes
}
dependencies {
passes project(':')
}
task passes {
dependsOn(configurations.passes)
}
Configuration c = configurations.detachedConfiguration(dependencies.create(project(':')))
task fails {
dependsOn(c)
}
Executing gradle :passes
passes, but executing gradle :fails
results in
FAILURE: Build failed with an exception.
* What went wrong:
Could not determine the dependencies of task ':fails'.
> Could not resolve all task dependencies for configuration ':detachedConfiguration1'.
> Could not resolve project :.
Required by:
project :
> Project : declares a dependency from configuration 'detachedConfiguration1' to configuration 'default' which is not declared in the descriptor for project :.
To me, the two scenarios looks pretty similar, so why is one task passing and why is the other failing?
At least a clue is that when adding the following
afterEvaluate {
println c.all
println configurations.passes.all
}
it prints
[configuration ':detachedConfiguration1']
[configuration ':annotationProcessor', configuration ':apiElements', configuration ':archives', configuration ':compile', configuration ':compileClasspath', configuration ':compileOnly', configuration ':default', configuration ':implementation', configuration ':passes', configuration ':runtime', configuration ':runtimeClasspath', configuration ':runtimeElements', configuration ':runtimeOnly', configuration ':testAnnotationProcessor', configuration ':testCompile', configuration ':testCompileClasspath', configuration ':testCompileOnly', configuration ':testImplementation', configuration ':testRuntime', configuration ':testRuntimeClasspath', configuration ':testRuntimeOnly']
Since the documentation for detachedConfiguration says that “Creates a configuration, but does not add it to this container.”, I rather interpreted that as the configuration is not visible, but that it still has knowledge about other configurations. Given the printout it looks as if the project dependency tries to resolve the default configuration within the detached configurations private container.
This then begets the question: How can the detached configuration get to know about the parallel configurations?
I should add that the goal is to be able to create an unknown number of classpaths based on different sets of dependencies, and it seemed that using detached configurations for these were ideal, if it weren’t for the fact that project self references break.