Contents

Gradle中传递命令行参数

1. 概述

有时,我们想从Gradle 执行各种需要输入参数的程序。

在本快速教程中,我们将了解如何从 Gradle 传递命令行参数。

2. 输入参数的类型

当我们想从 Gradle CLI 传递输入参数时,我们有两种选择:

  • 使用*-D* 标志设置系统属性
  • 使用*-P* 标志设置项目属性

一般来说,除非我们想在 JVM 中自定义设置,否则我们应该使用项目属性

尽管可以劫持系统属性来传递我们的输入,但我们应该避免这样做。

让我们看看这些属性的作用。首先,我们配置我们的build.gradle

apply plugin: "java"
description = "Gradle Command Line Arguments examples"
task propertyTypes(){
    doLast{
        if (project.hasProperty("args")) {
            println "Our input argument with project property ["+project.getProperty("args")+"]"
        }
        println "Our input argument with system property ["+System.getProperty("args")+"]"
    }
}

请注意,我们在任务中以不同的方式阅读它们。

我们这样做是因为project.getProperty()抛出MissingPropertyException以防我们的属性未定义

与项目属性不同,System.getProperty()在未定义属性的情况下返回null

接下来,让我们运行任务并查看其输出:

$ ./gradlew propertyTypes -Dargs=lorem -Pargs=ipsum
> Task :cmd-line-args:propertyTypes
Our input argument with project property [ipsum]
Our input argument with system property [lorem]

3. 传递命令行参数

到目前为止,我们已经了解了如何读取属性。在实践中,我们需要将这些属性作为参数发送给我们选择的程序。

3.1. 将参数传递给 Java 应用程序

在之前的教程中,我们解释了如何从 Gradle 运行 Java 主类 。让我们以此为基础,看看我们如何也可以传递参数。

首先,让我们在build.gradle中使用应用程序插件

apply plugin: "java"
apply plugin: "application"
description = "Gradle Command Line Arguments examples"
 
// previous declarations
 
ext.javaMainClass = "com.blogdemo.cmd.MainClass"
 
application {
    mainClassName = javaMainClass
}

现在,让我们看一下我们的主类:

public class MainClass {
    public static void main(String[] args) {
        System.out.println("Gradle command line arguments example");
        for (String arg : args) {
            System.out.println("Got argument [" + arg + "]");
        }
    }
}

接下来,让我们使用一些参数运行它:

$ ./gradlew :cmd-line-args:run --args="lorem ipsum dolor"
> Task :cmd-line-args:run
Gradle command line arguments example
Got argument [lorem]
Got argument [ipsum]
Got argument [dolor]

在这里,我们不使用属性来传递参数。相反,我们传递–args*标志和相应的输入*。

这是应用程序插件提供的一个很好的包装器。但是,这仅适用于 Gradle 4.9及更高版本。

让我们看看使用JavaExec任务会是什么样子。

首先,我们需要在build.gradle中定义它:

ext.javaMainClass = "com.blogdemo.cmd.MainClass"
if (project.hasProperty("args")) {
    ext.cmdargs = project.getProperty("args")
} else { 
    ext.cmdargs = ""
}
task cmdLineJavaExec(type: JavaExec) {
    group = "Execution"
    description = "Run the main class with JavaExecTask"
    classpath = sourceSets.main.runtimeClasspath
    main = javaMainClass
    args cmdargs.split()
}

让我们仔细看看我们做了什么。我们首先从项目属性中读取参数

由于这包含作为一个字符串的所有参数,因此我们使用split方法获取参数数组

接下来,我们将此数组传递给JavaExec任务的args属性

让我们看看当我们运行这个任务时会发生什么,使用*-P*选项传递项目属性:

$ ./gradlew cmdLineJavaExec -Pargs="lorem ipsum dolor"
> Task :cmd-line-args:cmdLineJavaExec
Gradle command line arguments example
Got argument [lorem]
Got argument [ipsum]
Got argument [dolor]

3.2. 将参数传递给其他应用程序

在某些情况下,我们可能希望将一些参数从 Gradle 传递给第三方应用程序。

幸运的是,我们可以使用更通用的Exec任务来做到这一点:

if (project.hasProperty("args")) {
    ext.cmdargs = project.getProperty("args")
} else { 
    ext.cmdargs = "ls"
}
 
task cmdLineExec(type: Exec) {
    group = "Execution"
    description = "Run an external program with ExecTask"
    commandLine cmdargs.split()
}

在这里,我们使用任务的commandLine属性来传递可执行文件以及任何参数。同样,我们根据空格分割输入。

让我们看看如何为ls命令运行它:

$ ./gradlew cmdLineExec -Pargs="ls -ll"
> Task :cmd-line-args:cmdLineExec
total 4
drwxr-xr-x 1 user 1049089    0 Sep  1 17:59 bin
drwxr-xr-x 1 user 1049089    0 Sep  1 18:30 build
-rw-r--r-- 1 user 1049089 1016 Sep  3 15:32 build.gradle
drwxr-xr-x 1 user 1049089    0 Sep  1 17:52 src

如果我们不想在任务中对可执行文件进行硬编码,这将非常有用。