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