Запустите задачу JavaExec в фоновом режиме, а затем завершите работу после завершения сборки - PullRequest
6 голосов
/ 23 октября 2011

Я пытаюсь выяснить, как запустить задачу JavaExec, которая порождает сервер Jetty, не блокируя последующие задачи. Кроме того, мне нужно будет прекратить этот сервер после завершения сборки. Есть идеи, как мне это сделать?

Ответы [ 4 ]

4 голосов
/ 02 марта 2017

Я обновил решение от @chrishuen, потому что вы больше не можете вызывать команду execute на задании.Вот мой рабочий build.gradle

import java.time.LocalDateTime
import java.util.concurrent.Callable
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

group 'sk.bsmk'
version '1.0-SNAPSHOT'

apply plugin: 'java'

task wrapper(type: Wrapper) {
  gradleVersion = '3.4'
}

class RunAsyncTask extends DefaultTask {
  @TaskAction
  def startAsync() {
    ExecutorService es = Executors.newSingleThreadExecutor()
    es.submit({
      project.javaexec {
        classpath = project.sourceSets.main.runtimeClasspath
        main = "Main"
      }
    } as Callable)

  }
}

task helloAsync(type: RunAsyncTask, dependsOn: compileJava) {
  doLast {
    println LocalDateTime.now().toString() + 'sleeping'
    sleep(2 * 1000)
  }
}
4 голосов
/ 22 июля 2016

Я знаю, что нить с 2011 года, но я все же наткнулся на проблему.Итак, вот решение, работающее с Gradle 2.14:

import java.util.concurrent.Callable
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors    

class RunAsyncTask extends DefaultTask {
    String taskToExecute = '<YourTask>'
    @TaskAction
    def startAsync() {
        ExecutorService es = Executors.newSingleThreadExecutor()
        es.submit({taskToExecute.execute()} as Callable)
    }
}


task runRegistry(type: RunAsyncTask, dependsOn: build){
    taskToExecute = '<NameOfYourTaskHere>'
}
1 голос
/ 23 октября 2011

Надеюсь, этот фрагмент даст вам некоторое представление о том, как это можно сделать.

Вы можете использовать замыкания слушателя сборки для запуска кода при начале / завершении сборки. Однако по какой-то причине закрытие gradle.buildStarted не работает в milestone-3, поэтому я заменил его на gradle.taskGraph.whenReady, что и помогает.

Затем вы можете вызвать задачу runJetty с помощью Task#execute() (обратите внимание, что этот API не является официальным и может исчезнуть), а также запустить его из ExecutorService, чтобы получить некоторое асинхронное поведение.

import java.util.concurrent.*

task myTask << {
  println "Do usual tasks here"
}

task runJetty << {
  print "Pretend we are running Jetty ..."
  while(!stopJetty){
    Thread.sleep(100)
  }
  println "Jetty Stopped."
}

stopJetty = false
es = Executors.newSingleThreadExecutor()
jettyFuture = null

//gradle.buildStarted { ... }
gradle.taskGraph.whenReady { g ->
  jettyFuture = es.submit({ runJetty.execute() } as Callable)
}

gradle.buildFinished {
  println "Stopping Jetty ... "
  stopJetty = true

  //This is optional. Could be useful when debugging.
  try{
    jettyFuture?.get()
  }catch(ExecutionException e){
    println "Error during Jetty execution: "
    e.printStackTrace()
  }
}
1 голос
/ 23 октября 2011

Вы не можете сделать это с JavaExec;вам придется написать собственное задание.

...