I have the following task in my build.gradle file:
task myTask(type:Exec) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout;
}
println "Output: $stdout"
}
When I run my task with ./gradlew myTask
, I get the following output:
> Configure project :
Output: retrovius
> Task :myTask FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':myTask'.
> execCommand == null!
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 2s
1 actionable task: 1 executed
The task successfully outputs my username (retrovius), then fails anyway. Any pointers for what I'm doing wrong?
Depending on what you want to achieve, the answer you found is probably still not correct.
All tasks have two main stages: configuration and execution. Everything you put in the outermost block to the task definition is part of the configuration. And the exec
method actually executes the command whenever that block of code is evaluated. So when you type:
task myTask() {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout;
}
println "Output: $stdout"
}
Then it means you are running the whoami
command no matter what task you specify. If you run gradle -i help
, it will print the name. I expect this is not what you intend.
Most of the time, you will want to run a command only when the task is actually executed. So if you want the command to only run if you type gradle -i myTask
, you will need to do defer it to the execution stage instead. There are two ways you can do that.
Either you can put everything in a doLast
block like this:
task myTask() {
doLast {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout
}
println "Output: $stdout"
}
}
Or you use the Exec
type, like you already tried. The reason it didn't work for you is that you need to configure it with the command you like - and not actually run the command through the exec
method. It could look like this:
task myTask(type: Exec) {
commandLine 'cmd', '/c', 'whoami'
standardOutput = new ByteArrayOutputStream()
doLast {
println "Output: $standardOutput"
}
}
You an also probably get rid of the cmd /c
part. And println
should only be used for debugging - use logger.info
(or .warn
, etc) if you need to output something to the user.
I figured out that the only thing I was doing wrong was to include the (type:Exec)
in the definition of my task. If I place the following code in my build.gradle file:
task myTask() {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout;
}
println "Output: $stdout"
}
I get the following output:
> Configure project :
Output: retrovius
BUILD SUCCESSFUL in 2s
My mistake must have been that I was defining the task to be of type exec, but not giving it a command to run. This reveals a fundamental misunderstanding of the exec task and task type on my part. If anyone knows more specifically what I did wrong, please feel free to comment and explain or post a better answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With