For some time now Gradle build files can be written in Kotlin, see for example this announcement post. Since this feature is pretty new, examples for common tasks are scarce.

If you have used Gradle to build a fat JAR, i.e. one that contains all dependencies next to the code you probably found this task:

task fatJar(type: Jar) {
    baseName = project.name + '-fat'
    from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

build.dependsOn fatJar

When you copy this to a build.gradle.kts file of course it does not work. So lets look at how to modify this task so it compiles with Kotlin!

val fatJar = task("fatJar", type = Jar::class) {
    baseName = "${project.name}-fat"
    manifest {
        attributes["Main-Class"] = "de.techdev.example.GradleKotlinMain"
    }
    from(configurations.runtime.map({ if (it.isDirectory) it else zipTree(it) }))
    with(tasks["jar"] as CopySpec)
}

tasks {
    "build" {
        dependsOn(fatJar)
    }
}

Setting the base name is pretty obvious. I additionally added a manifest attribute here because that is also required often.

The call to the from() method now needs parenthesis and instead of Groovy’s collect() Kotlin’s map() is used. Ternary operators don’t exist since if/else is an expression in Kotlin anyway.

The call to with() uses the jar task again, but it is not in the global scope so it is referenced by name. Since with() expects a CopySpec it is manually casted to that.

Finally the build task is again made dependent on the fatJar task. To avoid having to reference fatJar again by it’s name it is saved to a value before.

And that’s it, now you can use gradle build as with a Groovy build.gradle to build a fat JAR!