You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决多项目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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 11:22:14