问题描述:

I'm trying to figure out how to launch a JavaExec task that spawns a Jetty server without blocking subsequent tasks. Also, I will need to terminate this server after the build completes. Any idea how I can do this?

网友答案:

Hope this snippet will give you some insight on how it can be done.

You can used build listener closures to run code on build start/finish. However, for some reason, gradle.buildStarted closure does not work in milestone-3, so I have replaced it with gradle.taskGraph.whenReady which does the trick.

Then you can call the runJetty task using Task#execute() (Note, this API is not official and may disappear), and additionally, run it from an ExecutorService to get some asynchronous behaviour.

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()
  }
}
网友答案:

I know the thread is from 2011, but I still stumbled across the problem. So here's a solution working with 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>'
}
网友答案:

You can't do it with JavaExec; you'll have to write your own task.

网友答案:

I updated solution from @chrishuen because you cannot call execute on task anymore. Here is my working 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)
  }
}
相关阅读:
Top