Gradle多项目构建api(project(..))依赖失效及循环依赖问题求助
我有一个由多个子项目组成的Kotlin项目,所有子项目通过单个settings.gradle文件关联。此前运行正常,但在开发其他模块一周后,某模块出现大量编译错误:IntelliJ无法通过api project(':lib:content:model')导入依赖子项目的类。使用gradlew构建时出现循环依赖错误:
执行命令:
./gradlew :lib:game:model:build
错误信息:
FAILURE: Build failed with an exception. * What went wrong: Circular dependency between the following tasks: :lib:game:model:classes \--- :lib:game:model:compileJava +--- :lib:game:model:compileKotlin | +--- :lib:game:model:jar | | +--- :lib:game:model:classes (*) | | +--- :lib:game:model:compileJava (*) | | +--- :lib:game:model:compileKotlin (*) | | \--- :lib:game:model:kaptKotlin | | +--- :lib:game:model:jar (*) | | \--- :lib:game:model:kaptGenerateStubsKotlin | | \--- :lib:game:model:jar (*) | \--- :lib:game:model:kaptKotlin (*) \--- :lib:game:model:jar (*) (*) - details omitted (listed previously)
奇怪的是,同样使用api依赖机制的:lib:game:impl依赖:lib:game:api可以正常编译,只有:lib:game:model依赖:lib:content:model时出现问题。已尝试谷歌搜索但未解决,现附上项目结构、Gradle配置等信息,求助解决该问题,避免每次修改都发布到本地仓库。
项目结构
执行./gradlew -q projects输出:
------------------------------------------------------------ Root project 'test' ------------------------------------------------------------ Root project 'test' \--- Project ':lib' +--- Project ':lib:content' | \--- Project ':lib:content:model' \--- Project ':lib:game' +--- Project ':lib:game:api' +--- Project ':lib:game:impl' \--- Project ':lib:game:model' Included builds \--- Included build ':project-types'
相关Gradle配置
project-types模块配置
common/build.gradle:
plugins { id 'groovy-gradle-plugin' } repositories { mavenCentral() }
commons.gradle:
plugins { id 'java' } repositories { mavenCentral() mavenLocal() } dependencies { implementation 'com.fasterxml.jackson.core:jackson-core:2.13.4' implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.4' implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.4' implementation 'com.fasterxml.jackson.module:jackson-module-paranamer:2.13.4' implementation 'org.slf4j:slf4j-api:1.7.36' implementation 'ch.qos.logback:logback-classic:1.2.11' implementation 'commons-io:commons-io:2.11.0' implementation 'org.apache.commons:commons-lang3:3.12.0' implementation 'commons-codec:commons-codec:1.15' }
kotlin-project/build.gradle:
dependencyResolutionManagement { repositories { mavenLocal() mavenCentral() gradlePluginPortal() google() } } rootProject.name = 'project-types' include 'commons' include 'kotlin-project'
kotlin-project.gradle:
plugins { id 'commons' id 'org.jetbrains.kotlin.jvm' id 'org.jetbrains.kotlin.kapt' } dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' implementation 'org.jetbrains.kotlin:kotlin-reflect' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.6.4' implementation 'com.fasterxml.jackson.module:jackson-module-kotlin' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1' testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.1' testImplementation 'org.mockito:mockito-junit-jupiter:4.8.1' testImplementation 'org.mockito.kotlin:mockito-kotlin:4.0.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1' } test { useJUnitPlatform() } compileKotlin { kotlinOptions.jvmTarget = '17' kotlinOptions.freeCompilerArgs = ['-Xjsr305=strict', '-Xemit-jvm-type-annotations'] } compileTestKotlin { kotlinOptions.jvmTarget = '17' kotlinOptions.freeCompilerArgs = ['-Xjsr305=strict', '-Xemit-jvm-type-annotations'] } kapt { correctErrorTypes = true }
主项目配置
settings.gradle:
rootProject.name = 'test' includeBuild 'project-types' include 'lib:game' include 'lib:game:model' include 'lib:game:api' include 'lib:game:impl' include 'lib:content' include 'lib:content:model'
build.gradle:
plugins { id 'org.jetbrains.kotlin.jvm' version "1.7.21" apply false id 'org.jetbrains.kotlin.kapt' version "1.7.21" apply false } repositories { mavenCentral() }
子项目配置
lib/content/model/build.gradle:
plugins { id 'kotlin-project' } group 'cvazer.test' version '1.0.0' dependencies { }
lib/game/api/build.gradle:
plugins { id 'kotlin-project' } group 'cvazer.test' version '1.0.0' dependencies { }
lib/game/impl/build.gradle:
plugins { id 'kotlin-project' } group 'cvazer.test' version '1.0.0' dependencies { api project(':lib:game:api') }
lib/game/model/build.gradle(有问题的模块):
plugins { id 'kotlin-project' } group 'cvazer.test' version '1.0.0' dependencies { api project(':lib:content:model') }
1. 打破kapt任务循环
从错误栈可以看出,compileKotlin任务意外依赖了当前模块的jar任务,而jar又依赖classes,形成闭环。这是kapt插件的依赖传递异常导致的,需要显式调整任务依赖:
修改kotlin-project.gradle,添加任务依赖调整代码:
kapt { correctErrorTypes = true } // 移除compileKotlin对jar任务的依赖 tasks.named('compileKotlin') { dependsOn.remove(tasks.named('jar')) } // 移除kapt生成stubs任务对jar的依赖 tasks.named('kaptGenerateStubsKotlin') { dependsOn.remove(tasks.named('jar')) }
2. 排查模块间的隐性循环依赖
执行以下命令查看:lib:game:model的完整依赖树,确认是否存在双向依赖:
./gradlew :lib:game:model:dependencies
如果发现:lib:content:model间接依赖:lib:game:model,需要重构模块划分,将共享代码提取到新的公共模块,或者调整依赖方向。
3. 清理缓存并重新构建
执行清理命令清除旧的构建缓存,避免残留的错误依赖影响:
./gradlew clean :lib:game:model:build
4. 修复IntelliJ识别问题
如果IntelliJ仍然无法导入依赖类,执行以下操作:
- 点击
File -> Invalidate Caches...,选择Invalidate and Restart - 在Gradle工具窗口点击
Refresh all Gradle projects按钮重新导入项目
内容的提问来源于stack exchange,提问作者Yan Frankovski

