首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >通过Gradle运行Java类时传递系统属性和参数时出现问题

通过Gradle运行Java类时传递系统属性和参数时出现问题
EN

Stack Overflow用户
提问于 2014-05-16 05:31:13
回答 4查看 70.1K关注 0票数 87

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

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

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

我还发现了另外两篇关于通过Gradle执行Java程序的文章:one with an answer that advocates using apply plugin: "application" in the build file and gradle run at the command lineanother with answers advocating that approach as well as using task execute(type:JavaExec) in the build file and gradle execute at the command line。我已经尝试了这两种方法,但都没有成功。

我有两个问题:

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

无论我是否这样做:

build.gradle

代码语言:javascript
复制
apply plugin: 'application'
mainClassName = "com.mycompany.MyMain"

命令行

代码语言:javascript
复制
gradle run -Dmyproperty=myvalue

或者这样:

build.gradle

代码语言:javascript
复制
task execute (type:JavaExec) {
    main = "com.mycompany.MyMain"
    classpath = sourceSets.main.runtimeClasspath 
}

命令行

代码语言:javascript
复制
gradle execute -Dmyproperty=myvalue

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

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

这可能与第一个问题有关。例如,在exec-maven-plugin中,命令行参数本身是通过系统属性传入的。Gradle是这样的吗,还是有其他方法可以传递命令行参数?

我如何让这些变量通过?另外,使用apply plugin: 'application'task execute (type:JavaExec)哪个更好?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-05-16 06:23:47

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

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

似乎javaExec和应用程序插件的方法都是有效的。如果想要使用应用程序插件的一些其他特性(自动将发行版放在一起等),可能会更喜欢应用程序插件方法。

以下是解决方案:

JavaExec方法

命令行

代码语言:javascript
复制
gradle execute -Dmyvariable=myvalue -Dexec.args="arg1 arg2 arg3"

build.gradle

代码语言:javascript
复制
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()    
}

应用程序插件方法

命令行

代码语言:javascript
复制
gradle run -Dmyvariable=myvalue -Dexec.args="arg1 arg2 arg3"

build.gradle

代码语言:javascript
复制
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()    
}
票数 131
EN

Stack Overflow用户

发布于 2016-03-31 06:56:52

对于那些可能不想通过传递无关的Gradle prop来污染应用程序的系统属性的人,我建议使用命名空间来设置参数。

代码语言:javascript
复制
tasks.withType(JavaExec) {
    System.properties.each { k,v->
        if (k.startsWith("prefix.")) {
            systemProperty k - "prefix.", v
        }
    }
}

java ... -Dprefix.my.prop=true将通过my.prop

票数 12
EN

Stack Overflow用户

发布于 2018-03-03 04:03:27

我是gradle的新手,所以我需要这个,而gradle 4.6对我来说在命令行中似乎更容易一些。你可以传递一个args数组,而不是解析一个arg字符串,而且我也找到了一种用一行传递所有属性的方法。组合如下:

代码语言:javascript
复制
apply plugin: 'java'
apply plugin: 'org.springframework.boot'    <- for my project

task runApp(type: JavaExec) {
  classpath = sourceSets.main.runtimeClasspath

  main = 'testit.TomcatApp'

  // arguments to pass to the application
  //  args 'myarg1 -rest'    <- came in as 1 string

  args = ["--myarg1 with spaces even", "--myarg2"]

  // and to pass in all -D system property args:
  systemProperties = System.properties
}

gradle run -Dwhatever=xxx -Dmyarg2=hey

// Java reading them:
public static void main(String[] args) {
    for ( int i = 0; i < args.length; i++ )
        {
        logger.info( "** args [" + i + "] =" + args[i] + "=" );
        }
    logger.info( "** -Dwhatever =" + System.getProperty("whatever") + "=" );
    logger.info( "** -Dmyarg2 =" + System.getProperty("myarg2") + "=" );

[main] INFO testit.TomcatApp - ** args [0] =--myarg1 with spaces even=
[main] INFO testit.TomcatApp - ** args [1] =--myarg2=
[main] INFO testit.TomcatApp - ** -Dwhatever =xxx=
[main] INFO testit.TomcatApp - ** -Dmyarg2 =hey=
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23689054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档