Confusion in gradle --help and documentation for passsing system properties

I couldn’t understand why system properties were not being passed to my software.

It worked as expected when doing java -Dmyprop=myvalue main.java, but failed with ./gradlew -Dmyprop=myvalue :foo:run, where foo is a sub-project setup with its own functioning build script.

Here is the --help output that was confusing

...
USAGE: gradlew [option...] [task...]
...
--continue                         Continue task execution after a task failure.
--no-continue                      Stop task execution after a task failure.
-D, --system-prop                  Set system property of the JVM (e.g. -Dmyprop=myvalue).
-d, --debug                        Log in debug mode (includes normal stacktrace).
--daemon                           Uses the Gradle daemon to run the build. Starts the daemon if not running.
--no-daemon                        Do not use the Gradle daemon to run the build. Useful occasionally if you have configure
...

I expected the “JVM” to be that of my program.

After a long time of searching I figured out I needed to add:

tasks.named(‘run’) {systemProperties = System.properties}

to my build.gradle to get it to work.

With documentation alone I couldnt find help, and doing a System properties search in API didnt help.

Reading the “tutorials” doesnt help much either.
The only way I am able to write build scripts at all is with a clanker.

My point is, I have no idea how to use the documentation. Is it a skill issue? How would someone actually figure out that they need to do the above? How do learn to do something obscure that the clanker gets wrong?

Running a Gradle build can involve many JVMs. The CLI process, the daemon process, worker processes, test worker processes, compiler daemon processes, the JVM started by a JavaExec task like run if you did not disable forking, …

What you set from the CLI is only for the CLI and daemon JVM where most of the build logic is running, because you configure Gradle with it.

If you want to configure a task, you always have to do it manually. You for example also don’t set them for tests by setting them on the commandline.

This has many reasons, for example you might want to have different values for different tasks. And also, one of the biggest strengths of Gradle is to avoid unnecessary work. It you change a system property for Gradle or build logic, you should not automatically change the system property for each and every task, making the task out-of-date, as it could behave differently.

I would also not bluntly forward all system properties, but targetedly only the one you want forwarded.

Regarding discoverability, like I said, you always need to configure a task if you want it to have other configuration. By looking at the gradlew help --task run output or the application plugin documentation, you learn that it is a task of type JavaExec and on its documentation you see that there is a systemProperty method that you could use.

Or if you use a good IDE and especially if you use the Kotlin DSL, the IDE will also help with what is possible.

Could we clarify gradlew –help by specifying that it is for gradle JVM and not for project JVM? That part confused me the most.
It would also be nice if with gradle help —tasks foo , after it displays the task type, it would make a note saying “See docs for more options” or something. I know it could be clutter but I didnt think to check docs when I tried so maybe this is a small UX problem

If these suggestions make sense, Im happy to make a pull request and add them.

Also I dont think it makes sense for a build tool to need me to get a better IDE.

Feel free to open a feature request ticket or a pull request.
I’m just a user like you, in a ticket you will get feedback by the respective Gralde folks.