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

如何在项目初始化阶段执行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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:37:41