How can I fork a task into a separate cmd.exe shell?


(Jon Austen) #1

I am trying to get my build.gradle script to start a separate (forked) cmd.exe shell (that runs a simple Java webserver within it: ElementalHttpServer.java which is an open source project) and this method isn’t working for me ( it is blocking and the build script does not continue UNLESS there is a program error) . Can anyone tell me how I can do this the right way?

task(runWeb, dependsOn: 'classes', type: Exec) {
      //on windows
    commandLine 'cmd.exe', '/k', 'startWeb.bat'
      //store the output instead of printing to the console:
    standardOutput = new ByteArrayOutputStream()
      //extension method stopTomcat.output() can be used to obtain the output:
    ext.output = {
      return standardOutput.toString()
    }
  }
defaultTasks 'runWeb'

This starts a new cmd.exe window but it still blocks all remaining tasks from running:

commandLine 'cmd.exe', '/k', 'START', 'startWeb.bat'

And here is a screenshot that shows my build hanging just after it starts the cmd.exe window:

The wierd thing about this is that after it launches the shell, Gradle drops me to a directory prompt (as you see in screenshot within the console output) and then never continues until I close the cmd.exe shell that was opened. The popup shell window is blocking despite the fact that I used ‘/k’ and ‘START’ .

I get a similar result running Gradle build from the command line.


(Peter Niederwieser) #2

What’s ‘-k’? Isn’t it ‘cmd /c start foo.bat’? See Stack Overflow for a related thread.

PS: ‘ext.’ doesn’t stand for extension but for extra (property). I wonder what this ‘ext.output’ property is supposed to do there.


(Jon Austen) #3

I tried it without the standard output options in the task and got the same result.

If you ask me, “cmd.exe /k” is more proper than using “cmd.exe /c” since it “continues” rather than “stops”. Of course, I tried it both ways.

Thanks for the link to StackOverflow but after reading it, it isn’t the same issue.

You can see (and try) my project here: https://github.com/djangofan/WebDriverTestingTemplate/blob/master/parallelwebdriver/build.gradle

To be as simple as possible for you to reproduce, just download the .zip distro of my GitHub project (above) into a temp directory and then, from the “root” project run: “gradle.bat commonlib:compileJava parallelwebdriver:runWeb”.

That should only take you a couple minutes to try.


(Peter Niederwieser) #4

I’m afraid I won’t be able to help, as I don’t own a Windows box. What I can say is that there is no Gradle feature for this; you’ll have to solve it on the Java/Windows level.

I don’t know where you got the ‘ext.output’ from, but in all likelihood it is just dead code.


(Jon Austen) #5

Well, I will add some shell scripts to my project so that it doesn’t need to be just windows. In the meantime I will research it, but by the behavior I see in the above screenshot, it appears that the issue is specific to Gradle.


(Peter Niederwieser) #6

You don’t have to use an ‘Exec’ task (which is meant for blocking execution, because that’s what you want most of the time). You can write your own task that uses, for example, ‘java.lang.ProcessBuilder’, or even just Groovy’s ‘String.execute()’. That way, you can rule out that the problem is specific to Gradle.


(Jon Austen) #7

Great idea. Thanks, I will do that.