首页 > 解决方案 > Gradle exec task fails with "execCommand == null!"

问题描述

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?

标签: gradle

解决方案


根据您想要实现的目标,您找到的答案可能仍然不正确。

所有任务都有两个主要阶段:配置和执行。您放在任务定义最外层块中的所有内容都是配置的一部分。exec每当评估该代码块时,该方法实际上会执行该命令。所以当你输入:

task myTask() {
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine 'cmd', '/c', 'whoami'
        standardOutput = stdout;
    }
    println "Output: $stdout"
}

那么这意味着whoami无论您指定什么任务,您都在运行该命令。如果您运行gradle -i help,它将打印名称。我希望这不是你想要的。

大多数情况下,您只想在任务实际执行时才运行命令。因此,如果您希望命令仅在您键入时运行gradle -i myTask,您需要将其推迟到执行阶段。有两种方法可以做到这一点。

您可以将所有内容放在这样的doLast块中:

task myTask() {
    doLast {
        def stdout = new ByteArrayOutputStream()
        exec {
            commandLine 'cmd', '/c', 'whoami'
            standardOutput = stdout
        }
        println "Output: $stdout"
    }
}

或者你使用Exec type,就像你已经尝试过的那样。它对您不起作用的原因是您需要使用您喜欢的命令对其进行配置- 而不是通过该方法实际运行命令。exec它可能看起来像这样:

task myTask(type: Exec) {
    commandLine 'cmd', '/c', 'whoami'
    standardOutput = new ByteArrayOutputStream()
    doLast {
        println "Output: $standardOutput"
    }
}

你也可能摆脱了这个cmd /c部分。并且println只应用于调试 -如果您需要向用户输出某些内容,请使用logger.info(或等)。.warn


推荐阅读