I'm using Gradle 5.5. I have a Groovy-based build script that I'm trying to migrate to the Kotlin DSL. The jar
task contains the typical line for copying all dependencies to the JAR file:
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
I can't find a way to translate this line to the Kotlin DSL.
Let me give you some context. This is my original Groovy-based build script:
plugins {
id "org.jetbrains.kotlin.jvm" version "1.3.41"
}
group = "com.rhubarb_lip_sync"
version = "1.0.0"
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile "com.beust:klaxon:5.0.1"
compile "org.apache.commons:commons-lang3:3.9"
compile "no.tornado:tornadofx:1.7.19"
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
jar {
manifest {
attributes "Main-Class": "com.rhubarb_lip_sync.rhubarb_for_spine.MainKt"
}
// This line of code recursively collects and copies all of a project"s files
// and adds them to the JAR itself. One can extend this task, to skip certain
// files or particular types at will
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
And this is my Kotlin-based build script. It's working fine, except for that one line:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.3.41"
}
group = "com.rhubarb_lip_sync"
version = "1.0.0"
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation("com.beust:klaxon:5.0.1")
implementation("org.apache.commons:commons-lang3:3.9")
implementation("no.tornado:tornadofx:1.7.19")
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
tasks.withType<Jar> {
manifest {
attributes("Main-Class" to "com.rhubarb_lip_sync.rhubarb_for_spine.MainKt")
}
// ?
}
An uber-JAR—also known as a fat JAR or JAR with dependencies—is a JAR file that contains not only a Java program, but embeds its dependencies as well. This means that the JAR functions as an “all-in-one” distribution of the software, without needing any other Java code.
To activate the Kotlin DSL, simply use the . gradle. kts extension for your build scripts in place of . gradle .
Many other Kotlin DSL examples are available and you can find them on GitHub. As a starter, have a look at Kotlintest or kotlinx.html for instance. If you like to have a look at my examples or even want to contribute, the code is available here: SeKurity.
This small piece of source code contains four usages of apply, a method that makes use of Function Literals with Receiver. It's one of Kotlin's famous scope functions, which creates a scope on an arbitrary context object, in which we access members of that context object without additional qualifiers.
There’s also a Kotlin DSL for Gradle available: Gradle-Script-Kotlin Simon is a software engineer with 9+ years of experience developing software on multiple platforms including the JVM and Serverless environments. He currently builds scalable distributed services for a decision automation SaaS platform. Simon is a self-appointed Kotlin enthusiast.
To build a “fat” Jar of your Java or Kotlin project that contains all the dependencies within a single file, you can use the shadow Gradle plugin. I found it hard to find clear documentation on how it works using the Gradle Kotlin DSL (with a build.gradle.kts instead of build.gradle) so here is how I did it:
collect()
in groovy is map()
in Kotlin.
The ternary operator of groovy can be transformed into an if
in Kotlin.
The main difference is that configurations.compile in Kotlin is not a Configuration
but a Provider<Configuration>
. So either you get
the configuration out of the Provider, or you stay lazy by map
ping the Provider to another Provider. So I think it should work
from(configurations.compileClasspath.get().map { if (it.isDirectory()) it else zipTree(it) })
or
from(configurations.compileClasspath.map { config -> config.map { if (it.isDirectory) it else zipTree(it) } })
Note that compile
is deprecated for a long time now. Since use implementation
now to declare your dependencies, there's nothing anymore in the compile configuration, and you must get the dependencies out of the compileClasspath
one to build your uber jar.
Here is a great sample by Maksim Kostromin
val mainClass = "com.myproject" // Replace this, your project main name
tasks {
register("fatJar", Jar::class.java) {
archiveClassifier.set("all")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
attributes("Main-Class" to mainClass)
}
from(configurations.runtimeClasspath.get()
.onEach { println("add from dependencies: ${it.name}") }
.map { if (it.isDirectory) it else zipTree(it) })
val sourcesMain = sourceSets.main.get()
sourcesMain.allSource.forEach { println("add from sources: ${it.name}") }
from(sourcesMain.output)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With