我正在使用Kotlin构建一个Gradle插件,这是我使用Ktor和Coroutines的一个功能。插件必须作为类路径包含在第三部分项目中。
当我试图在另一个项目中使用插件时,问题来了,我得到了:
消费者项目的Caused by: java.lang.NoClassDefFoundError: kotlin/coroutines/Continuation
。
我试图隔离Coroutines依赖关系,并为Ktor应用可传递依赖关系,但没有成功。
我看到了太多不同的解决方案(https://github.com/Kotlin/kotlinx.coroutines/issues/430)比如应用ShadowJar来构建FatJar,但可能我在配置中遗漏了一些东西。一旦我应用了Shadow插件,jar大约是62Mb,即使应用minimize
大小的jar也是12MB。
插件的基本conf(基于Kotlin DSL的示例)是:
plugins {
`kotlin-dsl`
`maven-publish`
kotlin("jvm") version "1.3.10"
id("com.github.johnrengelman.shadow") version "4.0.3"
}
gradlePlugin {
plugins {
register("greet-plugin") {
id = "greet"
implementationClass = "GreetPlugin"
}
}
dependencies {
api("io.ktor:ktor-client-okhttp:1.0.1")
}
}
val sourcesJar by tasks.registering(Jar::class) {
classifier = "sources"
from(sourceSets.main.get().allSource)
}
val shadowJar: ShadowJar by tasks
shadowJar.apply {
baseName = "test"
classifier = ""
minimize()
}
完整的示例如下:https://github.com/cdsap/testPluginCoroutinesProblem
更详细的错误
java.lang.NoClassDefFoundError: kotlin/coroutines/Continuation
at io.ktor.client.engine.okhttp.OkHttp.create(OkHttp.kt:8)
at io.ktor.client.HttpClientKt.HttpClient(HttpClient.kt:36)
at io.ktor.client.HttpClientKt.HttpClient$default(HttpClient.kt:33)
at GreetPlugin.apply(GreetPlugin.kt:26)
at GreetPlugin.apply(GreetPlugin.kt:12)
我希望插件能在Ktor中正确地构建协程依赖关系,并且不会有大的jar作为依赖关系。
在我的例子中,shadowJar插件还没有生成胖jar。kotlin/coroutines/Continuation
程序包似乎是第一个未解决的程序包。
您可以使用jar实用程序进行检查:
jar tf app/build/libs/app-all.jar
胖罐子里有很多类,不仅仅是你的。
在我的案例中,build.gradle.kts
包含错误的配置:配置了task.jar
而不是task.shadowJar
build.gradle.kts
:的正确配置
val className = "com.stackoverflow.MainKt"
tasks.shadowJar {
manifest.attributes["Main-Class"] = className
archiveFileName.set("app-0.1-SNAPSHOT-all.jar")
}