无共享UI的KMP项目是否支持Room?iOS KSP编译报错求助
KMP项目中Room的配置问题(无共享UI场景)
问题描述
咨询
无共享UI的KMP项目是否支持Room?
详情
我有一个采用原生UI的KMP项目,怀疑shared.build.kts中的KSP配置在iOS代码中存在问题,初步排查发现iOS目标似乎不支持KSP。编译iOS项目时出现异常,相关配置及错误日志如下:
shared.build.kts配置
plugins { alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.androidLibrary) alias(libs.plugins.ksp) alias(libs.plugins.kmpNativeCoroutines) alias(libs.plugins.room) } kotlin { task("testClasses") androidTarget { compilations.all { kotlinOptions { jvmTarget = "1.8" } } } listOf( iosX64(), iosArm64(), iosSimulatorArm64() ).forEach { it.binaries.framework { baseName = "shared" isStatic = true } } sourceSets { commonMain.dependencies { implementation(libs.room.runtime) implementation(libs.sqlite.bundled) } commonTest.dependencies { implementation(libs.kotlin.test) } } } android { namespace = "com.testing.roomdbkmp" compileSdk = 34 defaultConfig { minSdk = 26 } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } } room{ schemaDirectory("$projectDir/schemas") } dependencies{ ksp(libs.room.compiler) }
TOML配置
[versions] agp = "8.4.1" kotlin = "1.9.23" compose = "1.6.7" compose-compiler = "1.5.13" compose-material3 = "1.2.1" androidx-activityCompose = "1.9.0" kmpNativeCoroutines = "1.0.0-ALPHA-28" ksp = "1.9.23-1.0.20" ktor = "2.3.10" room = "2.7.0-alpha03" sqlite = "2.5.0-SNAPSHOT" [libraries] kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" } compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" } compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" } compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" } compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose-material3" } room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } room-runtime-android = { module = "androidx.room:room-runtime-android", version.ref = "room" } room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } androidLibrary = { id = "com.android.library", version.ref = "agp" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlinCocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } room = { id = "androidx.room", version.ref = "room" } kmpNativeCoroutines = { id = "com.rickclephas.kmp.nativecoroutines", version.ref = "kmpNativeCoroutines" }
编译异常日志
error: java.lang.NoClassDefFoundError: javax/lang/model/type/TypeVisitor at androidx.room.compiler.codegen.XTypeName.<clinit>(XTypeName.kt:139) at androidx.room.solver.types.PrimitiveColumnTypeAdapter$Companion$Primitive.<clinit>(PrimitiveColumnTypeAdapter.kt:51) at androidx.room.solver.types.PrimitiveColumnTypeAdapter$Companion.createPrimitiveAdapters(PrimitiveColumnTypeAdapter.kt:70) at androidx.room.solver.TypeAdapterStore$Companion.create(TypeAdapterStore.kt:185) at androidx.room.processor.Context$typeAdapterStore$2.invoke(Context.kt:59) at androidx.room.processor.Context$typeAdapterStore$2.invoke(Context.kt:55) at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) at androidx.room.processor.Context.getTypeAdapterStore(Context.kt:55) at androidx.room.processor.Context.collectLogs(Context.kt:190) at androidx.room.DatabaseProcessingStep.process(DatabaseProcessingStep.kt:66) at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:132) at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62) at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:310) at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:308) at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt
解决方案
1. Room对KMP的支持说明
无共享UI的KMP项目完全支持Room,核心逻辑是仅在Android/JVM目标上运行KSP生成代码,生成的Kotlin代码可直接被iOS目标复用,无需在iOS端执行注解处理。
2. 修正KSP依赖配置
当前全局添加的ksp(libs.room.compiler)会触发KSP在iOS目标上运行,这是报错的核心原因。需将KSP依赖限定在Android目标:
dependencies { // 仅给Android目标配置KSP依赖 kspAndroid(libs.room.compiler) }
3. 版本兼容性调整
- 你使用的
room = "2.7.0-alpha03"是预览版,存在KMP兼容性风险,建议切换到稳定版本(如2.6.1),并确保Room的runtime、compiler版本完全一致。 - KSP版本
1.9.23-1.0.20与Kotlin1.9.23匹配,无需修改。
4. 验证iOS依赖(可选)
Room的runtime已包含多平台支持,commonMain中的依赖足够覆盖iOS场景,若需明确可添加:
sourceSets { iosMain.dependencies { implementation(libs.room.runtime) } }
5. 清理重建
修改配置后执行以下命令清除缓存并重新构建:
./gradlew clean ./gradlew assemble
错误原因解析
报错java.lang.NoClassDefFoundError: javax/lang/model/type/TypeVisitor是因为KSP是JVM工具,无法在iOS原生编译流程中运行。全局配置KSP会让Gradle尝试在iOS目标上执行注解处理,导致找不到JVM相关类。
内容的提问来源于stack exchange,提问作者Muhammad Ahmed AbuTalib
相关产品推荐
相关产品推荐

