如何在后台执行 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 中启动应用程序,我需要做以下事情:
- 使用 gulp
[gulp task: build]
. 构建静态资源
- 观察静态文件变化
[gulp task: watch]
,我不直接调用这个 gulp 任务,它是由 gradle 任务通过 Exec[=68 调用的=] class [gradle task: watch]
.
- 构建我的 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,我试过了,但是不行。也许我做错了什么。 :(
您可以使用 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
}
我正在使用 gradle 和 gulp 构建和启动基于 JDK6+ 的 JEE Web 应用程序,Web 容器是 Jetty。
Gulp用于处理静态资源,如concat和minify javascript/css文件。另外,我的 gulp 脚本中有一个 watch
任务,它用于监视静态文件更改并自动重建它们。
所以要在 Jetty 中启动应用程序,我需要做以下事情:
- 使用 gulp
[gulp task: build]
. 构建静态资源
- 观察静态文件变化
[gulp task: watch]
,我不直接调用这个 gulp 任务,它是由 gradle 任务通过 Exec[=68 调用的=] class[gradle task: watch]
. - 构建我的 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,我试过了,但是不行。也许我做错了什么。 :(
您可以使用 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
}