如何在后台执行 gradle 外部任务 (Exec)?

How to execute a gradle external task (Exec) in background?

我正在使用 gradle 和 gulp 构建和启动基于 JDK6+ 的 JEE Web 应用程序,Web 容器是 Jetty。

Gulp用于处理静态资源,如concat和minify javascript/css文件。另外,我的 gulp 脚本中有一个 watch 任务,它用于监视静态文件更改并自动重建它们。

所以要在 Jetty 中启动应用程序,我需要做以下事情:

  1. 使用 gulp [gulp task: build].
  2. 构建静态资源
  3. 观察静态文件变化 [gulp task: watch],我不直接调用这个 gulp 任务,它是由 gradle 任务通过 Exec[=68 调用的=] class [gradle task: watch].
  4. 构建我的 java 代码并启动 Jetty [gradle task: jettyRun]

因为我添加了 gradle 任务 watch 作为 jettyRun 任务的依赖项,所以我虽然只需要从命令行调用 gradle jettyRun,但我的应用程序将推出。但是结果和我想的不一样


以下是我的脚本文件:

build.gradle

apply plugin: 'war'
apply plugin: 'jetty'

repositories {
    jcenter()
}

// omit the dependencies here

task watch(type: Exec){
    workingDir "${projectDir}"
    // Pass build type to npm and gulp.
    commandLine "gulp", "watch"
}
jettyRun.dependsOn watch

gulpfile.js

var gulp = require('gulp');
gulp.task('build', function(callback) {
    // removed the code to make this question as simple as possible.
    if (callback != null) callback();
});

gulp.task('watch', function(callback) {
    gulp.watch(['./src/static/**/*.js'], ['build']);
    if (callback != null) callback();
});

结果:

问题:

现在,进程在执行 gradle watch 任务时挂起,没有更改为 gradle 执行 jettyRun 任务。我知道这个挂起是由 gulp 启动的监视进程引起的,因为它正在监视文件更改。但我希望gradle只启动gulp监视进程,return立即执行下一个jettyRun任务!

如何做到这一点?另外,我想从 stdout 查看 watch 任务的输出。

我知道java里面有一个ProcessBuilder,我试过了,但是不行。也许我做错了什么。 :(

Download all files

您可以使用 ProcessBuilder 在后台启动外部进程,让 gradle 继续执行其他任务。 finalizedBy 也可用于在 runJetty 完成后停止观看。

task watch {
    doFirst {
        println("Start watching")
        ext.process = new ProcessBuilder()
            .directory(projectDir)
            .command("gulp", "watch")
            .start()
    }
}

task stopWatching {
    doFirst {
        println("Stop watching")
        if (tasks.watch.process != null) {
            tasks.watch.process.destroy()
        }
    }
}

task runJetty {
    finalizedBy stopWatching
}