Hello team, I have a question about performance o...
# community-support
a
Hello team, I have a question about performance of extracting files from a jar dependency. I have the below task to unpack a jar file and use the output in other task (Mainly openAPI task to generate code)
Copy code
tasks.register<Copy>("unpackDependency") {
    from(zipTree(configurations.runtimeClasspath.get().filter {
        it.name.startsWith("party") && it.name.endsWith(".jar")
    }.singleFile)) {
        include("**/*.yaml")
        exclude("**/api-import-party-v1.yaml")
    }
    includeEmptyDirs = false
    into(unpackedDependencyDirectory)
}
My question is there a way to execute this task during the execution phase rather than resolving the dependencies in the configuration phase? I tried using doFirst but keep getting:
You cannot add child specs at execution time
and I think it is because of using the
from
command
s
You should be able to use the output directory of unpackDependency in another task without executing it, via
unpackDependency.flatMap { it.outputDirectory }
(where
unpackDependency
is the result of
tasks.register
). Have you tried that?
a
So u mean keeping the task as above and in the other task use:
unpackDependency.flatMap { it.outputDirectory }
? By keeping the task as it is, it will still be executed at configuration time right? I changed to this to avoid that:
Copy code
tasks.register<Copy>("unpackDependency") {
    val runtimeClasspath: FileCollection = configurations.runtimeClasspath.get()
    from(runtimeClasspath)
    doFirst {
        from(zipTree(runtimeClasspath.single {
            it.name.startsWith("party") && it.name.endsWith(".jar")
        })) {
            include("**/*.yaml")
            exclude("**/api-import-party-v1.yaml")
        }
    }
    into(unpackedDependencyDirectory)
}
s
Why would it be executed at configuration time? Maybe I'm missing something. The configuration would be resolved at configuration time but I think you can avoid this by creating a separate configuration for the party.jar and having your implementation configuration extend that one.
a
So what happens is that using
configurations.runtimeClasspath.get().filter
results in resolving the dependencies at configuration time, and that what I want to avoid.
s
I see, yes, a separate configuration would solve this. Alternatively,
FileCollection#matching
could help too (instead of filter). Or maybe simply wrapping the whole zipTree(…) in a lambda could be enough,
from({ zipTree(…)… })
a
So wrapping the whole
zipTree
still resolves the dependencies. Do u mind sharing the docs for creating a separate configuration.
s
val partyJarConfig = configurations.create(“partyJar”) configurations.implementation.extendsFrom(partyJarConfig) dependencies { partyJarConfig(“com.exampleparty jar0.0.1”) } And then you can use partyJar configuration in the zipTree and you don’t need filtering anymore.
a
I like that! Way better than going through all dependencies! Thanks alot Sergej!
v
Besides that, in similar cases where you cannot do that, don't use a task or type
Copy
, but inside the
doLast { ... }
a
copy { ... }
. But in that case make sure to also properly define the task inputs and outputs separately. Besides that,
Copy
/
copy
is almost never what you want, but usually you should use
Sync
/
sync
. And another thing to consider is, that this sounds more like a use-case for an artifact transform than a task.
👍 1
a
Great suggestions! @Vampire