我正在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
下找到。
希望这对遇到相同问题的其他人有所帮助:)