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

spa*_*ead 77 java gradle

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

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

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

我找到了另外两个SO帖子,它们通过Gradle处理Java程序执行:一个答案主张apply plugin: "application"在构建文件和gradle run命令行中使用,另一个答案提倡该方法以及task execute(type:JavaExec)在构建文件和构建文件gradle execute中使用命令行.我尝试了两种方法,但没有成功.

我有两个问题:

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

我是否这样做:

build.gradle:

apply plugin: 'application'
mainClassName = "com.mycompany.MyMain"
Run Code Online (Sandbox Code Playgroud)

命令行:

gradle run -Dmyproperty=myvalue
Run Code Online (Sandbox Code Playgroud)

或这个:

build.gradle:

task execute (type:JavaExec) {
    main = "com.mycompany.MyMain"
    classpath = sourceSets.main.runtimeClasspath 
}
Run Code Online (Sandbox Code Playgroud)

命令行:

gradle execute -Dmyproperty=myvalue
Run Code Online (Sandbox Code Playgroud)

无论哪种情况,myproperty都无法完成.从开始运行的代码MyMain.main (...)myproperty系统属性读取为null/missing.

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

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

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

spa*_*ead 117

弄清楚了.主要问题是,当Gradle分支新的Java进程时,它不会自动将环境变量值传递给新环境.必须通过systemProperties任务或插件的属性显式传递这些变量.

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

似乎javaExec和应用程序插件方法都是有效的.如果想要使用其他一些功能(自动组合分发等),人们可能会喜欢应用程序插件方法

以下是解决方案:

JavaExec方法

命令行:

gradle execute -Dmyvariable=myvalue -Dexec.args="arg1 arg2 arg3"
Run Code Online (Sandbox Code Playgroud)

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()    
}
Run Code Online (Sandbox Code Playgroud)

应用程序插件方法

命令行:

gradle run -Dmyvariable=myvalue -Dexec.args="arg1 arg2 arg3"
Run Code Online (Sandbox Code Playgroud)

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()    
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为应该是System.getProperties()(大写S). (3认同)
  • 请注意,默认分割不允许带空格的参数,例如 `-Dexec.args="--greeting 'hello there'"` – 不起作用,需要设置另一个分隔符。 (2认同)
  • 我还在寻找更直接的方法。这些方法似乎想要编辑/调整当前属性并传递它们。用于运行应用程序或服务的命令行和 Java 属性类似于“上下文”或“配置”设置。最好有一个插件可以将“运行参数”作为并排配置文件或其他功能执行之类的操作。我不想尝试以这种方式调试运行重要程序(如 Eclipse 或 Netbeans)的不同选项。。。(_我承认这当然可能只是我_) (2认同)
  • 请注意,如果未提供参数(例如,仅输入“gradle run”),“args System.getProperty("exec.args").split()”行似乎会抛出“NullPointerException”。 (2认同)
  • 使用:args System.getProperty(“ exec.args”,“”).split()避免在未提供args的情况下出现空指针异常。例如,即使“ gradle任务”也会在建议的build.gradle中引发异常。 (2认同)
  • 我花了一天的时间试图找出为什么我的 gradle 代码不起作用,非常感谢。 (2认同)

geg*_*geg 12

对于那些可能不想通过传递不相关的Gradle道具来污染应用程序的系统属性的人,我建议命名空间参数.

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

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