Gradle任务被终止后如何自动执行./gradlew --stop清理残留进程?
解决方案
方案1:添加JVM关闭钩子实现自动清理(改动最小)
你当前的实现是手动启动了多个独立的Gradle子进程,主进程被Ctrl+C终止时没有绑定子进程的销毁逻辑,因此会出现残留。只需要在任务中注册JVM关闭钩子,即可在进程收到终止信号时自动执行./gradlew --stop清理,修改后代码如下:
abstract class StartDevTask : DefaultTask() { private val developmentTasks = listOf( "dev-db", "run", "watch" ) @TaskAction fun startDevelopmentTasks() { // 注册关闭钩子,进程退出前自动清理所有Gradle守护进程 Runtime.getRuntime().addShutdownHook(Thread { ProcessBuilder("./gradlew", "--stop").start().waitFor() }) developmentTasks .map { ProcessBuilder("./gradlew", it).start() } .map { process -> Thread { process.waitFor() }.also { it.start() } } .map { it.join() } println("All processes finished") } } tasks.register<StartDevTask>("start-dev")
方案2:使用Gradle原生并行调度能力(更优实践)
手动通过ProcessBuilder启动多个Gradle进程属于冗余实现,完全可以复用Gradle内置的任务调度与并行能力,不需要自己维护进程、线程逻辑,也从根源上避免了残留进程的问题,实现代码更简洁:
// 直接将三个开发任务设为start-dev的依赖 tasks.register("start-dev") { dependsOn("dev-db", "run", "watch") // 强制该任务执行时开启并行,无需用户手动加--parallel参数 gradle.startParameter.isParallel = true } // 可选:如果有任务执行顺序要求,比如需要先启动dev-db再启动run,添加顺序约束即可 tasks.named("run") { mustRunAfter("dev-db") } tasks.named("watch") { mustRunAfter("dev-db") }
该方案下所有任务都运行在同一个Gradle上下文中,主进程终止时Gradle会自动回收所有任务相关的进程,不会产生残留,同时避免了多个Gradle守护进程的额外开销,符合Gradle的开发规范。
内容的提问来源于stack exchange,提问作者Some random IT boy
相关产品推荐
相关产品推荐

