在通过Gradle运行Java类时传递系统属性和参数的问题

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (166)

我试图通过Gradle运行一个命令行Java应用程序,作为快速集成测试的一部分。我正在从Maven移植我的构建脚本,在这里很容易通过exec-maven-plugin。我的两大要求是:

  • 能够将系统属性传递给可执行的Java代码
  • 能够将命令行参数传递给可执行的Java代码

请注意,我不想在构建脚本中读取这些属性,我试图在脚本构建和执行的Java程序中读取它们。

我发现,通过摇篮解决Java程序执行我尝试了两种方法,但都没有成功。

我有两个问题:

(1)我无法获得Java可执行文件来读取系统属性

我是否这样做:

build.gradle

apply plugin: 'application'
mainClassName = "com.mycompany.MyMain"

命令行

gradle run -Dmyproperty=myvalue

或这个:

build.gradle

task execute (type:JavaExec) {
    main = "com.mycompany.MyMain"
    classpath = sourceSets.main.runtimeClasspath 
}

命令行

gradle execute -Dmyproperty=myvalue

在任何一种情况下,myproperty都无法通过。从开始运行的代码MyMain.main (...)读取myproperty系统属性为空/缺少。

(2)我无法传递命令行参数

这可能与第一个问题有关。在exec-maven-plugin,例如,命令行参数本身也是经由系统属性传递英寸 这是Gradle的情况,还是有另一种方式来传递命令行参数?

我如何获得这些变量?另外,使用apply plugin: 'application'还是更好task execute (type:JavaExec)

提问于
用户回答回答于

主要问题是,当Gradle推出新的Java进程时,它不会自动将环境变量值传递到新环境。必须通过systemProperties任务或插件的属性显式传递这些变量。

另一个问题是理解如何通过命令行参数; 这些都是通过args任务或插件上的属性。和Maven一样exec-maven-plugin,它们应该通过另一个系统属性通过命令行传入,作为空间分隔的列表,然后split()在设置之前需要先列出,然后再args接受List对象。我已经命名了该属性exec.args,这是旧的Maven名称。

看起来javaExec和应用程序插件方法都是有效的。有人可能会喜欢应用程序插件方法,如果想要使用其他一些功能(自动将分布等)

以下是解决方案:

JavaExec方法

命令行

gradle execute -Dmyvariable=myvalue -Dexec.args="arg1 arg2 arg3"

build.gradle

task execute (type:JavaExec) {

    main = "com.myCompany.MyMain"
    classpath = sourceSets.main.runtimeClasspath 

    /* Can pass all the properties: */
    systemProperties System.getProperties()

    /* Or just each by name: */
    systemProperty "myvariable", System.getProperty("myvariable")

    /* Need to split the space-delimited value in the exec.args */
    args System.getProperty("exec.args", "").split()    
}

应用程序插件方法

命令行

gradle run -Dmyvariable=myvalue -Dexec.args="arg1 arg2 arg3"

build.gradle

apply plugin: 'application'
mainClassName = "com.mycompany.MyMain"
run {    
    /* Can pass all the properties: */
    systemProperties System.getProperties()

    /* Or just each by name: */
    systemProperty "myvariable", System.getProperty("myvariable")

    /* Need to split the space-delimited value in the exec.args */
    args System.getProperty("exec.args", "").split()    
}
用户回答回答于

对于那些不想通过传递不相关的Gradle道具来污染你的应用程序的系统属性的人,我推荐给你的参数命名。

tasks.withType(JavaExec) {
    System.properties.each { k,v->
        if (k.startsWith("prefix.")) {
            systemProperty k - "prefix.", v
        }
    }
}

java ... -Dprefix.my.prop=true 将传递 my.prop

扫码关注云+社区