简体   繁体   中英

How to create a Fat JAR with the Kotlin DSL?

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")
    }

    // ?
}

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)
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM