Creating a Fat Jar in Gradle with KotlinDSL

时间:2019-04-08 14:03:12

标签: gradle jar gradle-kotlin-dsl

So I'm translating example code of how to create a fat jar with Gradle from GroovyDSL to KotlinDSL (I'm using Gradle 5.3.1). I got the GroovyDSL code here:

jar {
    manifest {
        attributes "Main-Class": "com.baeldung.fatjar.Application"
    }
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

This is how far I've come: UPDATE: (latest version with feedback from JB Nizet)

jar {
    manifest {
        attributes("Main-Class" to "io.ktor.server.netty.EngineMain")
    }
    val compileConfig: Configuration = configurations.compile.get()
    from {
        compileConfig.
    }
}

The problem is that there isn't a collect-method on compileConfig which is a Configuration

The invocation of "from" is also a mystery to me. I'm fairly certain that the method originates in AbstractCopyTask. There are three versions of it: one takes a Object... sourcePaths while the other two have two parameters Object sourcepath and a Closure/Action but the Groovy version invokes it with only a single closure! My best guess is that the closure is automatically evaluated and the result coerced into an Object... invoking the first version of the method.

UPDATE: (latest version with feedback from JB Nizet)

If you want to test your ideas on how to solve this, here you can find this jar-task-configuration on a HelloWorld-Ktor project.

jar {
    manifest {
        attributes("Main-Class" to "io.ktor.server.netty.EngineMain")
    }
    from({
        val compileConfig = configurations.compile.get()
        logger.info("#files to iterate over: ${compileConfig.count()}")
        compileConfig.map { file -> 
            if (file.isDirectory) file else zipTree(file)
        }
    })
}

This compiles but doesn't produce a fat jar (via "gradle clean build"). If one looks at the output with info (via gradle clean build -x test --info), one finds the answer: no files are actually processed!

> Task :jar
#files to iterate over: 0
#files to iterate over: 0
Task ':jar' is not up-to-date because:
  Output property 'archiveFile' file /Users/SSchrod/progs/data-integration-salesforce-auto-cancellationkt/build/libs/data-integration-salesforce-auto-cancellation-0.1.51-SNAPSHOT.jar has been removed.
#files to iterate over: 0
:jar (Thread[Execution worker for ':',5,main]) completed. Took 0.068 secs.
:assemble (Thread[Execution worker for ':',5,main]) started.

With the code seemingly correctly translated to Kotlin, maybe the rest of my build-script is the problem? The original tutorial contained a call to the java-plugin in its build.gradle

apply plugin: 'java'

repositories {
    mavenCentral()
}

, which isn't present in my build.gradle.kts:

plugins {
    id("org.jetbrains.kotlin.jvm") version "1.3.20"
    id("pl.allegro.tech.build.axion-release") version "1.9.4"
    id("com.palantir.docker") version "0.21.0"
    id("com.github.johnrengelman.shadow") version "5.0.0"
}

repositories {
    mavenCentral()
    jcenter()
}

but adding it didn't seem to make a difference.

1 个答案:

答案 0 :(得分:0)

所以我现在有了shadowJar插件的解决方案:

plugins {
    kotlin("jvm") version "1.3.21"
    application
    id("com.github.johnrengelman.shadow") version "5.0.0"
}

application {
    mainClassName = "uk.co.which.stephan.server.ServerKt"
}

// repositories/dependencies/etc

tasks {
    withType<KotlinCompile> {
        kotlinOptions.jvmTarget = "1.8"
    }

    shadowJar {
        // defaults to project.name
        //archiveBaseName.set("${project.name}-fat")

        // defaults to all, so removing this overrides the normal, non-fat jar
        archiveClassifier.set("")
    }
}

完整的解决方案在我的HelloWorld-Ktor项目的solution / shadowJar分支的gradle.build.kts文件中。