Configure jar names lazily

For a reason independant of my will, I need to set lazily the name of generated jar.

Looks fine though, thanks to archiveFileName/archiveBaseName/archiveVersion that are supporting lazy values, tried with Zip tasks and it works well.

But I come across difficulties for jar task when the properties are set with Property resulting of another task.

Here’s a simple snippet presenting the issue:

plugins {
    id 'java'
}

def outputFile = layout.buildDirectory.file("generated/output.txt")

def writeOutputTask = tasks.register("writeOutput") {
    outputs.file(outputFile)
    doLast {
        def file = outputFile.get().asFile
        file.parentFile.mkdirs()
        file.text = "something"
    }
}

def fileContentProvider = writeOutputTask.map { task ->
    task.outputs.files.singleFile.text.trim()
}

tasks.register("customZip", Zip) {
    dependsOn(writeOutputTask)
    archiveBaseName.set(fileContentProvider)
    from("src/main/resources")
}

tasks.named("jar") {
    dependsOn(writeOutputTask)
    archiveBaseName.set(fileContentProvider)
}

During sync, multiple errors are occuring:

org.gradle.api.internal.provider.AbstractProperty$PropertyQueryException: Failed to query the value of task ':jar' property 'archiveFile'.
	at org.gradle.api.internal.provider.AbstractProperty.doCalculateValue(AbstractProperty.java:174)
[...]
Caused by: org.gradle.api.internal.provider.AbstractProperty$PropertyQueryException: Failed to query the value of task ':jar' property 'archiveFileName'.
[...]
Caused by: java.io.FileNotFoundException: D:\myproject\build\generated\output.txt (Le chemin d’accès spécifié est introuvable)

Looks like something related to jar task is eagerly retrieving the file name during configuration phase, contrary to Zip task.

This leads me to think that it is not possible to lazily set jar name (without error).

Is there something I am missing ? What are your thoughts?

One thought is, that you should not use dependsOn.
Practically any explicit dependsOn where the left-hand side is not a lifecycle task is code smell and usually a sign of not properly wiring tasks outputs to task inputs.

Actually, you do it correctly by using writeOutputTask.map, but the problem is, that archiveBaseName / archiveFile is not properly preserving the implicit task dependency (which is a Gradle bug you just found).

But to work-around that bug, I’d prefer to use inputs.property("archiveBaseName", fileContentProvider) or inputs.property("archiveBaseName", archiveBaseName) which then will have the base name as additional input but more important bears the implicit task dependency.

Besides that, pasting your exact code into my play project works exactly as you expect it to.

Even breaking task-configuration avoidance for the jar task using tasks.named("jar").get() still works fine.
But also breaking the laziness of the archiveFile property using tasks.named("jar").get().archiveFile.get() reproduces exactly your error.

So I agree, something in your build is misbehaving, breaking laziness regarding the archiveFile property. But this is not a Gradle bug, or if so, at a point that is not used in my play project.

The stacktrace you snipped away should point you exactly to the culprit that eagerly get()s the archiveFile property.

Thank you for your reply, I will try your workaround and get back to you.

For information, I am using gradle 8.14.3, not sure if it’s linked to this version.

My work-around is doing the same you did, just in a better way, it will not fix the problem.
Check the stacktrace (or provide it, then I’ll have a look) who breaks the laziness and that has to be fixed.

This is the complete stacktrace:

stacktrace.zip (3.9 KB)

Thanks

The cluprit is the IntelliJ Gradle integration here: intellij-community/plugins/gradle/tooling-extension-impl/src/com/intellij/gradle/toolingExtension/impl/util/GradleTaskUtil.java at master · JetBrains/intellij-community · GitHub so you should open a YouTrack issue about it.

Youtrack ticket opened: IDEA-379906 Lazy configuration of names for jar tasks are generating errors and warnings