Kotlin+Gradle未解析引用问题:多模块项目配置求助
Hey,我之前也踩过类似的Kotlin+Gradle跨模块引用的坑,结合你这个包含Android应用(projectA)和Spring Boot通用模块(projectB)的项目结构,给你几个靠谱的排查和解决方向:
先明确你的项目场景
你的项目结构和settings配置我先理清楚:
项目结构
project/ settings.gradle projectB/ # 通用代码(基于Spring Boot) build.gradle com/ foo/ bar/... projectA/ # Android应用 build.gradle com/ foo/ baz/...
settings.gradle 配置
rootProject.name = "project" include ":projectB" project(":projectB").projectDir = new File(rootDir, './projectB') include ":projectA" project(":projectA").projectDir = new File(rootDir, './projectA')
接下来一步步排查问题:
1. 先确认projectA有没有正确依赖projectB
Android模块要引用其他模块的代码,必须在projectA/build.gradle的dependencies块里添加依赖声明,别漏了:
dependencies { // 引用projectB模块 implementation project(":projectB") // 其他依赖... }
这里要注意:Spring Boot模块默认打包的是包含所有依赖的Fat Jar,这种Jar没法被Android模块正确引用,所以得调整projectB的构建配置。
2. 调整projectB的构建配置,生成可被引用的普通Jar
Spring Boot的插件会默认覆盖Jar任务,生成的是可运行的Fat Jar,我们需要让它同时生成一个普通的库Jar,供其他模块引用。修改projectB/build.gradle:
plugins { id 'org.springframework.boot' version 'x.x.x' // 替换成你的Spring Boot版本 id 'io.spring.dependency-management' version 'x.x.x' id 'java' id 'org.jetbrains.kotlin.jvm' version 'x.x.x' // 和projectA一致的Kotlin版本 } // 启用默认的Jar任务,生成普通库Jar jar { enabled = true } // 保留Spring Boot的可运行Jar配置(如果需要运行projectB的话) springBoot { mainClass = 'com.foo.bar.YourMainApplication' // 替换成你的主类路径 } // 确保Kotlin代码的编译目录被正确识别 sourceSets { main { kotlin { srcDirs = ['src/main/kotlin'] } } }
3. 确保两个模块的Kotlin版本完全一致
Kotlin版本不兼容是跨模块引用失败的常见原因,一定要让projectA和projectB用同一个版本。最好在根项目的build.gradle(如果没有就新建一个)里统一管理版本:
buildscript { ext { kotlin_version = "1.9.20" // 替换成你用的版本 spring_boot_version = "3.2.0" } repositories { mavenCentral() google() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version" } }
然后在projectA和projectB里引用这个统一版本,比如projectA的build.gradle:
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' version "$kotlin_version" }
projectB的build.gradle里的Kotlin插件版本也用这个变量。
4. 清理缓存并重新构建
做完上面的配置,一定要清理构建缓存,避免旧的编译产物干扰:
# 在项目根目录执行 ./gradlew clean :projectB:build :projectA:build --refresh-dependencies
如果用Android Studio的话,也可以点击File -> Sync Project with Gradle Files,然后Build -> Clean Project,再Rebuild Project。
5. 检查类的可见性和包名
最后确认一下:projectB里的类是不是public的(Kotlin默认是public,除非你写了internal),还有你在projectA里引用的包名有没有写错,比如projectB里的类是com.foo.bar.MyTool,那projectA里要写import com.foo.bar.MyTool,别把包名打错了。
内容的提问来源于stack exchange,提问作者Dan

