7

我最近从旧的 1.2 多平台切换到 1.3。不同之处在于,每个多平台模块只有一个 build.gradle 文件(我有 5 个),因此配置要少得多。但是,我似乎无法配置创建具有来自 jvm 平台的所有依赖项的可运行胖 jar。我曾经在我的 jvm 项目和 jar 任务中使用标准的“应用程序”插件,但这不再起作用了。我发现有“jvmJar”任务并对其进行了修改(设置 Main-class),但创建的 jar 不包含依赖项并在 ClassNotFoundException 上崩溃。我该怎么做?

这就是我现在所拥有的:

    jvm() {
        jvmJar {
            manifest {
                attributes 'Main-Class': 'eu.xx.Runner'
            }
            from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
        }

    }
4

4 回答 4

3

我确实碰到了那个颠簸并使用了这个工作。

1. 重组你的项目

让我们调用您的项目Project

创建另一个子模块 say subA,它将具有 gradle 符号Project:subA

现在,subA在它的 build.gradle 中有你的多平台代码(它是带有 apply :kotlin-multiplafrom 的 gradle 项目)

2.添加另一个子模块

创建另一个仅针对 jvm say 的子模块subB,它将具有 gradle 符号Project:subB

所以,subB会有插件:'application''org.jetbrains.kotlin.jvm'

3. 将你的模块添加为 gradle 依赖项(参见我的 build.gradle)

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.3.31'
    id "application"
}

apply plugin: "kotlinx-serialization"

group 'tz.or.self'
version '0.0.0'

mainClassName = "com.example.MainKt"

sourceCompatibility = 1.8

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

dependencies {
    implementation project(':subA')
}

您可以像常规 java 项目一样继续并构建 subB,甚至可以使用现有的插件,它会起作用

于 2019-07-27T11:19:16.777 回答
2

让它与 kotlin 1.3.61 中的多平台插件一起使用:

以下适用于主文件src/jvmMain/kotlin/com/example/Hello.kt

Hello.kt 还必须将其包指定为package com.example

我以这种方式配置了我的 jvm 目标:

kotlin {
    targets {
        jvm()

        configure([jvm])  {
            withJava()
            jvmJar {
                manifest {
                    attributes 'Main-Class': 'com.example.HelloKt'
                }
                from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
            }
        }
    }
}
于 2019-12-17T07:28:19.030 回答
1

让它与 luca992 所做的稍作修改的版本一起工作:

kotlin {
jvm() {
    withJava()
    jvmJar {
        manifest {
            attributes 'Main-Class': 'sample.MainKt'
        }
        from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
    }
}
...
}
于 2020-04-10T09:27:06.317 回答
1

让 gradle/multiplatform 工作的唯一方法似乎是无休止的反复试验;这是一场噩梦,它不是作为“构建”系统构建的,而是作为“构建系统”构建的;换句话说,这两个工具(一起或单独)是一种仅实现插件制造商预期的单一软件开发生命周期的方法,但是,如果您设计了所需的软件生命周期和 CI/CD 系统,并且现在您尝试实现该工程,使用这些工具来实现它比使用脚本、代码或 maven 来实现它要困难得多。有许多的原因:

  • 由于插件制造商只公开了最低可配置性,编码约定发生了巨大变化,可能只允许访问他们自己的个人项目所需的东西。
  • 文档更新很差;Kotlin、gradle 和插件变化如此之快,我开始严重质疑这些工具的实用性。

因此,在撰写本文时,这似乎是使用 kotlin 1.3.72、multiplatform 1.3.72、ktor 1.3.2 和 gradle 6.2.2(使用 kts 格式)时使用的正确语法。

请注意,fatJar 似乎正确组装但无法运行,它找不到类,因此我包含了我同时使用的第二个 runLocally 任务。

这不是一个完整的解决方案,所以我讨厌在这里发布它,但据我所知......这是我在任何地方都能找到的最完整和最新的解决方案。

//Import variables from gradle.properties
val environment: String by project
val kotlinVersion: String by project
val ktorVersion: String by project
val kotlinExposedVersion: String by project
val mySqlConnectorVersion: String by project
val logbackVersion: String by project
val romeToolsVersion: String by project
val klaxonVersion: String by project
val kotlinLoggingVersion: String by project
val skrapeItVersion: String by project
val jsoupVersion: String by project
val devWebApiServer: String by project
val devWebApiServerVersion: 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 {
        compilations {
            val main = getByName("main")
            tasks {
                register<Jar>("buildFatJar") {
                    group = "application"
                    manifest {
                        attributes["Implementation-Title"] = "Gradle Jar File Example"
                        attributes["Implementation-Version"] = archiveVersion
                        attributes["Main-Class"] = "com.app.BackendAppKt"
                    }
                    archiveBaseName.set("${project.name}-fat")
                    from(main.output.classesDirs, main.compileDependencyFiles)
                    with(jar.get() as CopySpec)
                }
                register<JavaExec>("runLocally") {
                    group = "application"
                    setMain("com.app.BackendAppKt")
                    classpath = main.output.classesDirs
                    classpath += main.compileDependencyFiles
                }
            }
        }
    }
    js {
        browser { EXCLUDED FOR LENGTH }
    }
    sourceSets { EXCLUDED FOR LENGTH }
}
于 2020-07-07T03:19:28.243 回答