Kotlin多平台项目自定义Gradle插件同步报错求助
Kotlin多平台自定义Gradle插件报错解决
问题概述
我在为Kotlin多平台项目的app模块实现自定义Gradle插件时,同步项目反复报错:提示需初始化至少一个Kotlin Target,但我已完成配置。添加extensions.getByType(ApplicationExtension::class.java)后触发NoClassDefFoundError,尝试在插件中初始化target也无效果。
报错堆栈信息
> Configure project :app mmd is Coming com.android.application e: Please initialize at least one Kotlin target in 'app (:app)'. Read more https://kotl.in/set-up-targets w: The following Kotlin source sets were configured but not added to any Kotlin compilation: * commonMain * commonTest You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'. See https://kotl.in/connecting-source-sets w: Missing 'androidTarget()' Kotlin target in multiplatform project 'app (:app)'. The Android Gradle plugin was applied without creating a corresponding 'android()' Kotlin Target: plugins { id("com.android.application") kotlin("multiplatform") } kotlin { androidTarget() // <-- please register this Android target } FAILURE: Build failed with an exception. * What went wrong: com/android/build/api/dsl/ApplicationExtension > com/android/build/api/dsl/ApplicationExtension * Try: > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. > Get more help at https://help.gradle.org. * Exception is: java.lang.NoClassDefFoundError: com.android.build.api.dsl.ApplicationExtension at ApplicationGradlePlugin.apply(ApplicationGradlePlugin.kt:24) ... Caused by: java.lang.ClassNotFoundException: com.android.build.api.dsl.ApplicationExtension at org.gradle.internal.classloader.VisitableURLClassLoader$InstrumentingVisitableURLClassLoader.findClass(VisitableURLClassLoader.java:187) ... 215 more CONFIGURE FAILED in 6s
BuildSrc中的自定义插件代码
class ApplicationGradlePlugin : Plugin<Project> { override fun apply(target: Project) { with(target) { val libs = extensions.getByType<VersionCatalogsExtension>().named("libs") println("mmd is Coming") println(libs.findPlugin("androidApplication").get().get().pluginId) pluginManager.apply(libs.findPlugin("kotlinMultiplatform").get().get().pluginId) pluginManager.apply(libs.findPlugin("androidApplication").get().get().pluginId) extensions.getByType(ApplicationExtension::class.java) println("mmd done his job..") } } }
app模块的build.gradle.kts配置
import org.jetbrains.compose.desktop.application.dsl.TargetFormat plugins { alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.composeMultiplatform) alias(libs.plugins.composeCompiler) alias(libs.plugins.kotlin.serialization) alias(libs.plugins.androidApplication) id("com.sample.myproject.application-plugin")// --> this is my custom plugin } kotlin { android { compilations.all { kotlinOptions.jvmTarget = "21" } } jvm("desktop") sourceSets { val desktopMain by getting androidMain.dependencies { // android dependencies } commonMain.dependencies { // common dependencies } desktopMain.dependencies { // desktop dependencies } } } android { namespace = "com.sample.myproject" compileSdk = libs.versions.android.compileSdk.get().toInt() defaultConfig { applicationId = "com.sample.myproject" // other configurations }
已尝试的无效操作
在插件中初始化target,无效果:
extensions.getByType(KotlinMultiplatformExtension::class).apply { androidTarget() jvm("desktop") }
解决方案
问题根源
- 插件依赖缺失:BuildSrc未添加Android Gradle插件的依赖,导致运行时找不到
ApplicationExtension类。 - 插件应用顺序混乱:自定义插件手动重复应用
kotlinMultiplatform和androidApplication插件,与app模块plugins块的声明冲突,导致KMP插件先执行时无法找到Android配置,触发target未初始化报错。 - 扩展获取时机错误:在Android插件未完全应用时就尝试获取
ApplicationExtension,导致类加载失败。
修复步骤
1. 给BuildSrc添加Android Gradle插件依赖
在buildSrc/build.gradle.kts中添加依赖,确保能找到Android相关类:
plugins { `kotlin-dsl` } repositories { google() mavenCentral() } dependencies { // 使用libs catalog引用(推荐) implementation(libs.plugins.android.application.get().get().pluginId) implementation(libs.plugins.kotlin.multiplatform.get().get().pluginId) // 或者直接指定版本(如果未用libs catalog) // implementation("com.android.tools.build:gradle:8.4.0") // implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20") }
2. 重构自定义插件逻辑
移除重复应用插件的代码,改用插件监听机制,确保在目标插件加载完成后再处理扩展:
class ApplicationGradlePlugin : Plugin<Project> { override fun apply(target: Project) { with(target) { val libs = extensions.getByType<VersionCatalogsExtension>().named("libs") println("mmd is Coming") // 监听Android Application插件加载完成事件 pluginManager.withPlugin("com.android.application") { val androidExt = extensions.getByType(ApplicationExtension::class.java) // 在这里添加你的自定义Android配置逻辑,比如统一设置compileSdk等 println("mmd done his job..") } // 可选:监听Kotlin Multiplatform插件加载完成事件,做默认配置 pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { val kmpExt = extensions.getByType(KotlinMultiplatformExtension::class.java) // 比如添加默认target或配置sourceSets } } } }
3. 调整app模块plugins块顺序
将自定义插件移到所有基础插件之后,确保依赖插件先加载:
plugins { alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.composeMultiplatform) alias(libs.plugins.composeCompiler) alias(libs.plugins.kotlin.serialization) alias(libs.plugins.androidApplication) id("com.sample.myproject.application-plugin") // 移到最后 }
4. 验证Kotlin Target配置
app模块中的kotlin块已经正确配置了android和desktop target,无需修改,确保插件逻辑不会覆盖这些配置即可。
内容的提问来源于stack exchange,提问作者AbolfazlHaghpanah
相关产品推荐
相关产品推荐

