如何在项目初始化阶段执行shadowJar任务并复制产物至指定子项目?
问题分析与解决方案
你的核心需求是在项目构建流程中,先执行org.eclipse.buildship.gradleprop.languageserver子项目的shadowJar任务生成Jar包,再将产物复制到org.eclipse.buildship.gradleprop.provider子项目的libs目录。原init.gradle的问题在于时机错误:在配置阶段直接尝试获取未执行任务的输出文件,且copy操作在配置阶段执行而非任务阶段,导致逻辑失效。
解决方案1:根项目build.gradle中配置任务依赖(推荐)
在根项目的build.gradle中通过任务依赖绑定逻辑,完全符合Gradle声明式构建的设计:
// 根目录build.gradle subprojects { afterEvaluate { project -> if (project.name == 'org.eclipse.buildship.gradleprop.provider') { // 关联语言服务子项目 def languageServerProj = project(':org.eclipse.buildship.gradleprop.languageserver') // 获取shadowJar任务实例 def shadowJarTask = languageServerProj.tasks.named('shadowJar').get() // 为provider项目创建专属复制任务 project.tasks.create('copyLanguageServerJar', Copy) { // 确保shadowJar执行完成后再复制 dependsOn shadowJarTask // 从shadowJar的输出文件中读取产物 from shadowJarTask.outputs.files // 复制到provider的libs目录 into project.file('libs') } // 绑定到provider项目的构建流程,比如让assemble任务自动触发复制 project.tasks.named('assemble').configure { dependsOn project.tasks.named('copyLanguageServerJar') } } } }
执行时只需运行./gradlew :org.eclipse.buildship.gradleprop.provider:assemble,Gradle会自动先执行shadowJar再完成复制。
解决方案2:改进init.gradle写法(全局场景适用)
如果需要通过init.gradle全局生效,调整执行时机到任务阶段:
// init.gradle gradle.projectsLoaded { allprojects { project -> project.afterEvaluate { if (project.name == 'org.eclipse.buildship.gradleprop.provider') { def languageServerProj = project(':org.eclipse.buildship.gradleprop.languageserver') def shadowJarTask = languageServerProj.tasks.named('shadowJar').get() def copyTask = project.tasks.create('copyLangServerJar', Copy) { dependsOn shadowJarTask from shadowJarTask.outputs.files into project.file('libs') } // 绑定到预构建任务,确保构建前完成复制 project.tasks.named('preBuild').configure { dependsOn copyTask } } } } }
替代思路:依赖管理替代手动复制
如果provider项目需要直接使用languageserver的shadowJar产物,无需手动复制,直接在provider子项目的build.gradle中添加依赖:
// provider子项目build.gradle dependencies { // 依赖languageserver的shadowJar产物(shadow插件默认提供shadow配置) implementation project(path: ':org.eclipse.buildship.gradleprop.languageserver', configuration: 'shadow') }
Gradle会自动处理依赖传递,将shadowJar引入到provider的类路径中,更符合Gradle的依赖管理规范。
内容的提问来源于stack exchange,提问作者Nikolai
相关产品推荐
相关产品推荐

