I am trying to execute a command with gradle with the below task:
task stopServer(dependsOn: war, type: Exec) << {
commandLine 'pkill -9 tomcat'
}
When I run it I get the following error:
* What went wrong:
Execution failed for task ':stopServer'.
> execCommand == null!
And when my task is like this:
task stopServer(dependsOn: war) << {
exec {
commandLine 'pkill -9 tomcat'
}
}
I get this error:
* What went wrong:
Execution failed for task ':stopServer'.
> A problem occurred starting process 'command 'pkill -9 tomcat''
Can you tell me where I am going wrong in each of these approaches?
If neither of above are right way of executing then please specify the way of doing it probably with an example.
To run a Gradle command, open a command window on the project folder and enter the Gradle command. Gradle commands look like this: On Windows: gradlew <task1> <task2> … e.g. gradlew clean allTests.
If you press the run button in Android Studio, it triggers the corresponding Gradle task and starts the application. You can also run Gradle via the command line. To avoid unnecessary local installation, Gradle provides a wrapper script which allows you to run Gradle without any local installation.
In Gradle terms this means that you can define tasks and dependencies between tasks. Gradle guarantees that these tasks are executed in the order of their dependencies, and that each task is executed only once. These tasks form a Directed Acyclic Graph.
I believe you're looking for this:
task stopServer(dependsOn: war, type: Exec) {
commandLine "pkill", " -9", "tomcat"
}
The main difference is very subtle - I just deleted two characters. The <<
is gone from the task definition. The other difference is that the commandLine
expects the executable to be passed in separately from the arguments to it.
I removed the <<
because of an important idea in gradle: the build lifecycle. There's configuration and execution phases (that's not all, but it's enough to explain this).
The <<
is like saying doLast
- it adds the closure you pass to the end of the actions (the execution phase) for this task. So that means here, it's going to try and execute the command like normal (it's an Exec
object, after all), and only then, once it's executed, will it call your block - the block setting commandLine
. So when it's executing, execCommand
really is null, and would be until your block was run. This is the heart of your problem.
Without the <<
(also known as left-shift), that same block runs during the configuration phase. So the exec command gets set before it runs, and it works.
Here is another solution that works well for the same error if you have a standalone exec task that you want to run from the commandline but do not want to run in Android Studio as part of your build.
This will always run the configuration of "myExecTask" but will only execute doMyExecTask when it is explicitly run via "gradle myExecTask"
/**
* Actually run exec task in doLast phase
*/
task doMyExecTask << {
def hasProperties = project.hasProperty('SOME_PROPERTY');
if (hasProperties) {
myExecTask.commandLine "echo", "$SOME_PROPERTY"
} else {
println "ERROR: Unable to run task. Missing properties."
}
}
/**
* Configure exec task, this always runs
*/
task myExecTask(type: Exec) {
dependsOn doMyExecTask
workingDir 'path/to/executable'
}
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