This message was deleted.
# community-support
s
This message was deleted.
v
To start with, any explicit
dependsOn
that does not have a lifecycle task on the left-hand side is a code smell and a strong sign that you are not properly wiring outputs to inputs which would give you necessary dependencies automatically. Besides that, a
duplicatesStrategy
is seldomly what you want. If you got an error that files are duplicated, then in 98.7 % of the cases it means you should fix the source of this, making sure files are not duplicated. The more idiomatic version of what you have would be
Copy code
tasks.register<Tar>("runtimeDependenciesDist") {
    archiveClassifier = "dependencies"
    from(configurations.runtimeClasspath)
    include("*.jar")
}
Typically, afair the runtime classpath contains only jars anyway, so even this might be sufficient:
Copy code
tasks.register<Tar>("runtimeDependenciesDist") {
    archiveClassifier = "dependencies"
    from(configurations.runtimeClasspath)
}
The "skip when no source" check you can trick with this:
Copy code
tasks.register<Tar>("runtimeDependenciesDist") {
    archiveClassifier = "dependencies"
    from(configurations.runtimeClasspath)

    from(Files.createTempFile(temporaryDir.toPath(), null, null))
    eachFile {
        if (file.parentFile == temporaryDir) {
            exclude()
        }
    }
}
I'm not sure whether there is a more elegant way, but at least it works by having a file to pack but then using
eachFile
(not
exclude("...")
) to skip that file.
thank you 1
e
also couldn't this be handled by the distribution plugin anyway?
e.g.
Copy code
plugins {
    distribution
}

distributions {
    create("runtimeDependencies") {
        contents {
            from(configurations.runtimeClasspath)
        }
    }
}
./gradlew runtimeDependenciesDistTar
thank you 1
v
Would as well not create the file if there are no contents, wouldn't it? It also just declares a tar task and a zip task for the distribution. I don't think you win much with using the
distribution
plugin here, if all you want is a tar archive of the runtime classpath.
👍 1
e
well it's true that it skips if the sources are empty, it sounds like a distribution-like task though
👌 1
a
Thank you for sharing this knowledge guys. It is very helpful. I have a follow up question as the original problem I faced that led to the requirement above was different. I have the following maven publishing setup in my build.
Copy code
publishing {
    publications {
        create<MavenPublication>(project.name) {
            from(components["java"])
            artifact(tasks["runtimeDependenciesDist"])
        }
    }
}
This was running into an error when the the runtimeDependenciesDist task did not create a
.tar
file due to the runtimeClasspath being empty. I wonder if there is a way to add conditionality in our publishing setup here such that it does not attempt to publish the .tar archive if it does not exists.
Another thing to note I took the ideas from the creating Creating "uber" or "fat" JARs section in Gradle's documentation for defining runtimeClasspath as the source for my tar task. I wonder if the dependsOn practice shared should apply there as well. Jar is not a lifecycle task as far as my knowledge goes.
v
Jar is not a lifecycle task as far as my knowledge goes
That's correct. We use the term "lifecycle tasks" for tasks that do not do any own action but are just there to depend on other tasks like
build
,
assemble
, or
check
. I think that example is written badly and should be reworked to follow best practices, for example as
Copy code
tasks.register<Jar>("uberJar") {
    archiveClassifier = "uber"

    from(sourceSets.main.get().output)
    from(configurations.runtimeClasspath.flatMap {
        it
            .asFileTree
            .matching { include("*.jar") }
            .elements
            .map { it.map { zipTree(it) } }
    })
}
Besides that imho those fat jars are an abuse and bad practice anyway and only bring many drawbacks for no real gain. Fat jars like Spring Boot projects build them are better. And if needing such a bad-practice fat jar, one should at least John R. Engelman's
shadow
plugin which at least sails around some of the cliffs you will hit with them.