【问题标题】:Creating a Fat Jar in Gradle with KotlinDSL使用 Kotlin DSL 在 Gradle 中创建 Fat Jar
【发布时间】:2019-08-29 17:04:14
【问题描述】:

因此,我将如何使用 Gradle 创建胖 jar 的示例代码从 GroovyDSL 转换为 KotlinDSL(我使用的是 Gradle 5.3.1)。 我得到了 GroovyDSL 代码 here:

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

这是我已经走了多远: 更新:(来自 JB Nizet 反馈的最新版本)

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

问题是compileConfig 上没有collect-method,它是Configuration

“来自”的调用对我来说也是一个谜。我相当确定该方法源自AbstractCopyTask。它有三个版本:一个接受一个 Object... sourcePaths 而另外两个有两个参数 Object sourcepath 和一个 Closure/Action 但 Groovy 版本只用一个闭包调用它!我最好的猜测是自动评估闭包并将结果强制转换为 Object... 调用该方法的第一个版本。

更新:(JB Nizet 提供反馈的最新版本)

如果您想测试您的解决方法here,您可以在 HelloWorld-Ktor 项目中找到此 jar-task-configuration。

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

这会编译但不会生成胖 jar(通过“gradle clean build”)。 如果查看带有 info 的输出(通过 gradle clean build -x test --info),可以找到答案:实际上没有文件被处理!

> 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.

代码似乎正确地转换为 Kotlin,也许我的构建脚本的其余部分是问题所在? 原始教程在其build.gradle 中包含对 java-plugin 的调用

apply plugin: 'java'

repositories {
    mavenCentral()
}

,我的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()
}

但添加它似乎并没有什么不同。

【问题讨论】:

  • Groovy collect() == Kotlin map()。 compileConfig.map { if (it.isDirectory()) it else zipTree(it) }
  • 在 groovy 示例中传递给 from 的是一个闭包。见docs.gradle.org/current/javadoc/org/gradle/api/…:参数可以是闭包。
  • @JBNizet 收集地图的好地方!我没有注意到它,因为它没有出现在 JavaDoc 中。 (原因 - 当然 - 因为 map 是 Iterable 上的扩展函数,而不是原始接口的一部分)。不幸的是,该项目仍然没有产生一个胖罐子:'(
  • 在另一个帖子中查看我的答案:stackoverflow.com/a/69508845/3792198 这个问题是重复的。

标签: gradle jar gradle-kotlin-dsl


【解决方案1】:

所以我现在有了 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 文件中找到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    • 2017-06-07
    • 2019-03-06
    • 1970-01-01
    • 1970-01-01
    • 2017-03-27
    • 1970-01-01
    相关资源
    最近更新 更多