如何解决多项目Gradle构建中的任务依赖问题?
问题描述
概述
我有一个多项目Gradle构建,包含多个Java应用子项目和一个基础Java库子项目,每个应用子项目都依赖该基础库。需要在build生命周期中为每个应用生成包含自身类文件及所有依赖类文件的Jar包(即fatJar)。
遇到的问题
理想情况下,我希望重写默认的Jar任务,使其通过引入runtimeClasspath中的依赖文件来实现fatJar的功能,配置如下:
jar { manifest.attributes 'Main-Class': application.mainClass archiveBaseName = "${rootProject.name}-${project.name}" duplicatesStrategy = DuplicatesStrategy.INCLUDE from configurations.runtimeClasspath.collect{it.isDirectory() ? it : zipTree(it) } }
但这会抛出Gradle错误:
Task ':app1:jar' uses this output of task ':app-base:jar' without declaring an explicit or implicit dependency. Possible solutions: 1. Declare task ':app-base:jar' as an input of ':controlling-sim:jar'. 2. Declare an explicit dependency on ':app-base:jar' from ':controlling-sim:jar' using Task#dependsOn. 3. Declare an explicit dependency on ':app-base:jar' from ':controlling-sim:jar' using Task#mustRunAfter.
我不理解该错误产生的原因,认为跨项目任务间无需声明显式依赖。
另一种方案是注册一个名为fatJar的Jar类型任务,但如果在buildSrc/src/main/groovy/application-conventions.gradle中添加如下配置使其在build生命周期中执行,会触发相同错误:
tasks.assemble.dependsOn fatJar
不添加上述依赖时,fatJar任务可正常运行,但需要用户手动执行该任务。
核心问题:如何避免上述错误?
完整项目结构
buildSrc/src/main/groovy/base-conventions.gradle
plugins { id 'java-library' } repositories { mavenLocal() mavenCentral() }
buildSrc/src/main/groovy/application-conventions.gradle
plugins { id 'java' id 'application' } repositories { mavenLocal() mavenCentral() } dependencies { implementation project(':app-base') } jar { manifest.attributes 'Main-Class': application.mainClass archiveBaseName = "${rootProject.name}-${project.name}" duplicatesStrategy = DuplicatesStrategy.INCLUDE from configurations.runtimeClasspath.collect{it.isDirectory() ? it : zipTree(it) } } // Alternative... /*tasks.register('fatJar', Jar) { manifest { attributes 'Main-Class': application.mainClass } group = 'build' archiveBaseName = "${rootProject.name}-${project.name}" duplicatesStrategy = DuplicatesStrategy.INCLUDE from configurations.runtimeClasspath.collect{it.isDirectory() ? it : zipTree(it) } }*/
app-base/build.gradle
plugins { id 'base-conventions' } dependencies { api 'com.xyz:lib-java:1.0' implementation 'ch.qos.logback:logback-classic:1.3.14' }
app1/build.gradle
plugins { id 'application-conventions' } application { mainClass = 'com.xyz.app1.Main' }
已尝试方案
- 显式添加任务间依赖可解决问题,但并非合理方案:
jar { dependsOn project(":app-base").tasks.jar }
- 添加assemble任务与自定义任务的依赖,同样触发错误:
tasks.assemble.dependsOn fatJar
内容的提问来源于stack exchange,提问作者SirPodgio
相关产品推荐
相关产品推荐

