I’m trying to make configuration resolution as lazy as possible.
In particular, the following pattern emerges quite often in our build scripts:
apply plugin: 'java'
configurations {
external
}
dependencies {
external 'group:artifact:version' // zip archive in some maven repo
}
jar {
from zipTree(configurations.external.singleFile)
}
It does not look lazy at all - ‘external’ configuration is getting resolved even on ‘./gradlew classes’, which does not require ‘jar’ task at all. I’ve tried
jar {
from configurations.external.asFileTree
}
instead and it acts way better. Apparently, it cannot be transformed into zipTree:
jar {
from zipTree(configurations.external.asFileTree) // fails
}
Is there a way to get a zipTree without configuration resolution? Or maybe there’s some other way to get dependency content repacked (spec reuse, etc)?
Thanks in advance for your time and consideration.
It’s worth noting that if the input Configuration includes project dependencies you’ll need to add an explicit dependency to it to ensure all the task dependencies get added property.
I want to clarify this example a bit. I believe the configuration is still resolved during the configuration phase, but only when the jar task is in the task graph… and this still feels slightly wrong to me.
Here’s an example I derived from Peter’s referenced answer on the old forums:
configurations {
api {
incoming.beforeResolve { println "Resolving api configuration!" }
}
}
repositories {
jcenter()
}
dependencies {
api 'junit:junit:4.12'
}
task extractApi(type: Sync) {
doFirst { println 'Running extractApi task...' } //just to guarantee this task has some console output
from { // use of closure defers evaluation until execution time (KM apparently not??)
configurations.api.collect { zipTree(it) }
}
into "$buildDir/api/"
}
task clean {
doLast {
delete "$buildDir/api/"
}
}
Example usages: $ gradle clean returns:
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
Perfect, this is as expected.
$ gradle extractApi returns:
Resolving api configuration!
> Task :extractApi
Running extractApi task...
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
Why is the resolution happening during configuration? Is this just semantics?
It’s not, it’s happening during execution when snapshotting inputs for the :extractApi task, which is why it looks as though its happening before that task executes, but it’s certainly during the execution “phase”.
The clear evidence of this not happening during project configuration is that we do not see that configuration being resolved when running other tasks, such as clean, which means we are definitely not eagerly resolving that configuration.