Kotlin多平台项目替换Ktor为Quarkus后quarkusDev执行失败
解决KMP项目中Quarkus Dev模式空指针异常问题
问题背景
在Kotlin多平台(KMP)项目中替换Ktor为Quarkus后端,迁移代码后quarkusRun可正常执行,但quarkusDev抛出空指针异常:
Cannot invoke "io.quarkus.bootstrap.workspace.ArtifactSources.getSourceDirs()"
核心原因
Quarkus Dev模式需要扫描项目源码与资源目录以支持热重载等功能,KMP模块的sourceSets配置与Quarkus插件的预期不匹配,导致插件无法正确获取ArtifactSources对象,进而触发NPE。
解决方案
1. 移除冗余的sourceSets配置
Kotlin JVM插件已默认配置src/main/kotlin和src/test/kotlin作为源码目录,手动指定会干扰Quarkus插件的源码检测逻辑。删除build.gradle.kts中的以下代码块:
sourceSets { main { kotlin.srcDirs("src/main/kotlin") } test { kotlin.srcDirs("src/test/kotlin") } }
2. 确保Quarkus与Kotlin版本兼容
Kotlin 2.0.x需要Quarkus 3.12及以上版本支持,检查quarkusPlatformVersion是否符合要求,若版本过低则升级。
3. 明确配置资源目录(可选)
若项目缺少资源目录或Quarkus仍无法识别,在kotlin块中补充资源目录配置:
kotlin { compilerOptions { jvmTarget = JvmTarget.JVM_17 javaParameters = true } sourceSets { val main by getting { resources.srcDir("src/main/resources") } val test by getting { resources.srcDir("src/test/resources") } } }
确保src/main/resources目录存在(可空),Quarkus需要该目录加载配置文件。
4. 清理Gradle缓存
执行以下命令清理缓存后重新运行Dev模式:
./gradlew clean quarkusDev
修改后的完整build.gradle.kts示例
import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.kotlinJvm) kotlin("plugin.allopen") version "2.0.21" id("io.quarkus") } val quarkusPlatformGroupId: String by project val quarkusPlatformArtifactId: String by project val quarkusPlatformVersion: String by project dependencies { implementation(projects.shared) implementation(libs.logback) implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")) implementation("io.quarkus:quarkus-kotlin") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("io.quarkus:quarkus-arc") implementation("io.quarkus:quarkus-resteasy-jackson") implementation("io.quarkus:quarkus-logging-json") implementation("io.quarkus:quarkus-config-yaml") testImplementation("io.quarkus:quarkus-junit5") testImplementation("io.rest-assured:rest-assured") } group = "org.example.project" version = "1.0.0" tasks.withType<Test> { systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager") } allOpen { annotation("jakarta.ws.rs.Path") annotation("jakarta.enterprise.context.ApplicationScoped") annotation("jakarta.persistence.Entity") annotation("io.quarkus.test.junit.QuarkusTest") } kotlin { compilerOptions { jvmTarget = JvmTarget.JVM_17 javaParameters = true } }
内容的提问来源于stack exchange,提问作者Wyatt
相关产品推荐
相关产品推荐

