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

如何同时运行Gradle多模块项目的两个子项目任务?

如何在Gradle Monorepo中并行运行独立的开发服务器任务

你的Monorepo结构如下:

monorepo
 build.gradle
 /api
   build.gradle
 /webapp
   build.gradle

你希望并行运行:api:bootRun和:webapp:runDev这两个无前置依赖(在bootJar执行前无关联)的开发任务,此前用GPars尝试失败,以下是问题分析和可行解决方案:

你的GPars代码问题

你当前的代码存在一个关键错误:在svc.submit中传入的是整个tasksToRun数组,而非当前迭代的单个taskToRun,导致每次调用runDevTaskFromProject都会重复处理全部任务,这是无法正确并行的核心原因。

修复后的GPars代码如下:

tasks.register("dev") {
    def tasksToRun = ['api:bootRun', 'webapp:runDev']

    GParsPool.withPool { ExecutorService svc -> 
        tasksToRun.each { taskToRun ->
            // 传入当前迭代的单个任务,而非整个任务列表
            svc.submit({ runDevTaskFromProject(taskToRun) })
        }
    }
}

def runDevTaskFromProject(String projectTask) {
    try {
        String[] components = projectTask.split(':')
        GradleRunner.create()
            .withProjectDir(new File(projectDir, components[0]))
            .withArguments(components[1])
            .forwardOutput()
            .build()
    } catch (Exception e) {
        println "Run Failed: ${e.message}"
        return
    }
}

同时建议用new File(projectDir, components[0])替代字符串拼接,避免跨平台路径分隔符问题。

更优方案:Gradle Workers API(官方推荐)

Workers API是Gradle官方提供的并行任务执行方案,无需依赖第三方库,能更好地集成Gradle的缓存、输入输出跟踪机制,由Gradle统一管理线程池,稳定性更强:

import org.gradle.workers.WorkerExecutor
import javax.inject.Inject

tasks.register("dev") {
    def workerExecutor = project.getServices().get(WorkerExecutor.class)
    def tasksToRun = ['api:bootRun', 'webapp:runDev']

    tasksToRun.each { taskToRun ->
        workerExecutor.submit(RunDevTask.class) { parameters ->
            parameters.projectTask.set(taskToRun)
            parameters.rootProjectDir.set(projectDir)
        }
    }
}

abstract class RunDevTask implements Runnable {
    @Inject
    abstract WorkerExecutor getWorkerExecutor()

    @Input
    final Property<String> projectTask = project.objects.property(String)

    @InputDirectory
    final DirectoryProperty rootProjectDir = project.objects.directoryProperty()

    @Override
    void run() {
        try {
            String[] components = projectTask.get().split(':')
            GradleRunner.create()
                .withProjectDir(rootProjectDir.file(components[0]).get().asFile)
                .withArguments(components[1])
                .forwardOutput()
                .build()
        } catch (Exception e) {
            println "Run Failed: ${e.message}"
        }
    }
}

关于原生并行参数的说明

你可能会考虑用--parallel参数配合dependsOn实现,但需要注意::api:bootRun和:webapp:runDev都是持续运行的开发服务器任务,Gradle默认会等待任务执行完成才会启动下一个,而开发服务器不会自动退出,因此这种方式无法实现真正的并行运行,还是需要通过独立进程(GradleRunner)或Workers API的方式处理。

内容的提问来源于stack exchange,提问作者bear

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:50:25