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

gradle, java

Solution

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

Problem

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)`?

Original source

Related problems