Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
207 views
in Technique[技术] by (71.8m points)

Problems passing system properties and parameters when running Java class via Gradle

I am trying to run a command-line Java app via Gradle as part of a quick integration test. I am porting my build scripts from Maven, where this was easily done via exec-maven-plugin. My two big requirements are:

  • Being able to pass system properties to the executable Java code
  • Being able to pass command-line args to the executable Java code

Please note that I am not trying to read these properties in the build script, I'm trying to read them in the Java program that the script builds and executes.

I have found two other SO posts that address Java program execution via Gradle: one with an answer that advocates using apply plugin: "application" in the build file and gradle run at the command line, and another with answers advocating that approach as well as using task execute(type:JavaExec) in the build file and gradle execute at the command line. I have tried both approaches and have not succeeded.

I have two problems:

(1) I cannot get the Java executable to read the system properties

Whether I do this:

build.gradle:

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

Command line:

gradle run -Dmyproperty=myvalue

Or this:

build.gradle:

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

Command line:

gradle execute -Dmyproperty=myvalue

In either case, myproperty does not make it through. The code that begins running from MyMain.main (...) reads the myproperty system property as null/missing.

(2) I cannot pass command line arguments

This is probably related to the first problem. In exec-maven-plugin, for example, command line args were themselves passed in via a system property. Is that the case with Gradle, or is there another way to pass command line arguments?

How do I get these variables through? Also, is it better to use apply plugin: 'application' or task execute (type:JavaExec)?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Figured it out. The main issue is that when Gradle forks a new Java process, it does not automatically pass the environment variable values along to the new environment. One has to explicitly pass these variables via the systemProperties property of the task or plugin.

The other issue was understanding how to pass command-line args; these are via the args property on the task or plugin. As with the Maven exec-maven-plugin, they should be passed in on the command line via yet another system property, as a space-delimited list that then needs to be split() before setting args, which accepts List objects. I've named the property exec.args, which is the old Maven name.

It seems both the javaExec and application plugin approach are valid. One might favor the application plugin approach if one wants to use some of its other features (automatically putting together a distribution, etc.)

Here are the solutions:

JavaExec Approach

Command Line:

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()    
}

Application Plugin Approach

Command Line:

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()    
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...