从工件的.jar运行时找不到 Kotlinx 协程类



我正在IntelliJ Idea IDE上开发一个使用kotlinx协程的Kotlin桌面应用程序。

这是我的build.gradle文件:

plugins {
id 'application'
id 'org.jetbrains.kotlin.jvm' version '1.3.60'
}
mainClassName = 'MainKt'
group 'my_group_name'
version '1.01'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
jar {
manifest {
attributes 'Main-Class': 'MainKt'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}

通过 IDE 运行项目时一切正常,但是当我生成.jar工件并通过java -jar file.jar运行它时,使用协程类时会引发以下异常:

Exception in thread "Thread-2" java.lang.NoClassDefFoundError: kotlinx/coroutines/GlobalScope
Caused by: java.lang.ClassNotFoundException: kotlinx.coroutines.GlobalScope
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)

为什么 Kotlinx 协程在生成的.jar工件上运行java -jar file.jar时不起作用?

经过很长时间寻找这个问题的解决方案,我找到了两种解决方法。


第一

生成的.jar工件不包含该 Kotlinx 协程类,因为该工件是在将协程添加为依赖项之前在IntelliJ Idea 上设置的。

因此,工件配置不包括 Kotlinx 协程(似乎它不会与新的依赖项添加和删除同步(。

为了解决这个问题,可以:

  • 手动将依赖项添加到项目生成配置(在项目设置上(,或者;
  • 删除配置,然后重新创建。

第二

创建一个 fatJar 任务 o gradle,如下所示

jar {
manifest {
attributes 'Main-Class': 'MainKt'
}
}
task fatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'MainKt'
}
baseName = project.name
from {
configurations.runtimeClasspath.collect {
it.isDirectory() ? it : zipTree(it)
}
}
with jar
}

并运行该 gradle 任务

gradle fatJar

输出可以在build/libs下找到。


希望这对遇到相同问题的其他人有所帮助:)

最新更新