gradle-kotlin-dsl - 使用 Kotlin Gradle DSL 从 ktor Kotlin 多平台项目创建胖 jar

标签 gradle-kotlin-dsl ktor kotlin-multiplatform

尝试为包含 ktor 服务器组件的 kotlin 多平台项目创建一个可运行的 jar,使用 Kotlin Gradle DSL 构建。

我看到了几个问题,包括Create fat jar from kotlin multiplatform project它询问并回答了如何在 Groovy 中创建 gradle 构建文件,但是你如何在 kotlin dsl 中做到这一点?

报告工作的常规代码是:

kotlin {
jvm() {
    withJava()
    jvmJar {
        manifest {
            attributes 'Main-Class': 'sample.MainKt'
        }
        from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
    }
}
...
}

这将如何转化为 Kotlin DSL?我尝试了许多变体,其中一些可以编译和运行,但没有创建所需的输出……一个可运行的 jar。

最佳答案

我花了 3 天时间试图让 fat jar 子工作,以下是解决方案以及解决方案澄清之前的内容:
我早期犯的错误

  • 不应该冲进 docker,应该先让 fat jar 在本地工作。
  • withJava() 被排除在外,这是 36 个工时的主要浪费……WTF 是这个函数的重点吗?
  • 依赖(构建):为什么 jar 任务类型不知道这一点我已经不明白了。
  • main.compileDependencyFiles:我曾经使用它来代替下面参数中的 map 。
  • main.output.classesDirs:在其他解决方案中缺失,似乎包含您的实际代码。

  • 注意:不需要影子插件,这太棒了(恕我直言,gradle 插件往往不能很好地协同工作)。
    注意:版本控制很重要,因为在某些情况下,此堆栈的更改速度似乎比文档快 50 倍,此解决方案使用了以下内容:
  • Kotlin 1.3.72
  • Gradle 6.5
  • Ktor 1.3.2

  • 代码 :
    //Import variables from gradle.properties
    val environment: String by project
    val kotlinVersion: String by project
    val ktorVersion: String by project
    
    //Build File Configuration
    plugins {
        java
        kotlin("multiplatform") version "1.3.72"
    }
    
    group = "com.app"
    version = "1.0-SNAPSHOT"
    
    repositories {
        mavenCentral()
        jcenter()
        jcenter {
            url = uri("https://kotlin.bintray.com/kotlin-js-wrappers")
        }
        maven {
            url = uri("https://jitpack.io")
        }
    }
    
    //Multiplatform Configuration
    kotlin {
        jvm {
            withJava()
            compilations {
                val main = getByName("main")
                tasks {
                    register<Jar>("buildFatJar2") {
                        group = "application"
                        dependsOn(build)
                        manifest {
                            attributes["Main-Class"] = "com.app.BackendAppKt"
                        }
                        from(configurations.getByName("runtimeClasspath").map { if (it.isDirectory) it else zipTree(it) }, main.output.classesDirs)
                        archiveBaseName.set("${project.name}-fat2")
                    }
                }
            }
        }
        js {
            browser {
    
            }
        }
        sourceSets { SKIPPED FOR LENGTH }
    }
    
    我希望这可以为某人节省 3 天,如果您发现改进,请告诉我(我也在学习)。 Kotlin、gradle、多平台、docker……都很难处理,他们需要并行更新文档恕我直言,否则 jetbrains 注定要失败。
    潜在的改进 :
  • 生成的 jar 看起来比它应该的大得多,里面有大量不必要的东西,怀疑更改为编译路径而不是运行时路径会解决这个问题(确认大小减少 30%)。
  • 也许更明显的属性。
  • 另外值得注意的是,我读了一篇文章恰本地建议不应将 fatJars 部署到 docker,Java 依赖项应作为镜像的一部分构建。
  • 关于gradle-kotlin-dsl - 使用 Kotlin Gradle DSL 从 ktor Kotlin 多平台项目创建胖 jar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61245847/

    相关文章:

    ktor - Kotlin Multiplatform - 使用 Ktor 处理响应 http 代码和异常

    kotlin - 接收表单参数到 Ktor 服务器

    kotlin - IgnoreUnknownKeys 仅适用于 Kotlinx 和 Ktor 的一种类型

    gradle - 使用Kotlin MPP插件时,简单和源集依赖项之间有什么区别?

    android - 使用 Gradle Kotlin-DSL 时如何使用 flavorDimensions 为每种 flavor 组合设置不同的 applicationId?

    intellij-idea - 预期的类没有实际声明

    ios - Android Studio KMM 应用程序项目 - 为 ios 平台构建失败

    java - Kotlin 有多平台锁吗?

    Gradle:在 settings.gradle.kts 和 buildSrc/build.gradle.kts 之间共享存储库配置

    gradle - Kotlin DSL : Import a versions. gradle.kts 进入另一个 build.gradle.kts