'Can't add jvmArgs using add(), why?

Can anyone explain why the first sample working while the second does nothing?

test {
    jvmArgs '-Xdebug',
            '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=4000'
}

test {
    jvmArgs.add('-Xdebug')
    jvmArgs.add('-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=4000')
}


Solution 1:[1]

Because in the second example this method is invoked. You get the list, modify it but the changes are not reflected to settings - read only access. In the first example this method is invoked and arguments passed are set.

Here's the explanation, a copy of the list is returned (it's for safety, security reasons - mutable types should be always returned as a copy)

public List<String> getJvmArgs() {
   List<String> args = new ArrayList<String>();
   for (Object extraJvmArg : extraJvmArgs) {
      args.add(extraJvmArg.toString());
   }
   return args;
}

Solution 2:[2]

I found this problematic with the normal command line arguments using Gradle as well -- Even to the extent that Example 1 works and Example 2 will fail to add the extra argument:

  • runArgs is set in the main build.gradle

As follows:

 ext {
     runArgs = [ '-server=localhost', '-port=8080' ];
 }

Simply appending to the command line appears challenging (see below).


Example 1:

debug.doFirst(){

//  ... <snip> ...

        //  command line arguments
        //
    println "      debug args (a):  ${args}."
    runArgs.add( "-memo=${project.name}:debug" );
    args = runArgs;
    println "      debug args (b):  ${args}."


}

Output is correct, shows "-memo" parameter is added but also the passed-in args have been replaced by the script variable using this approach.

debug args (a):  [-server, localhost, -port, 8080 ].
debug args (b):  [-server=localhost, -port=8080, -memo=Client:debug].

Example 2:

debug.doFirst(){

//  ... <snip> ...

        //  command line arguments
        //
    println "      debug args (a):  ${args}."
    args.add( "-memo=${project.name}:debug" );
    println "      debug args (b):  ${args}."


}

Output (correctly?) shows there was no add(), per answer: from Opal above.

debug args (a):  [-server, localhost, -port, 8080 ].
debug args (b):  [-server, localhost, -port, 8080 ].

I've posted this example to show that there may be alternatives to accepting the status quo, i expect the jvmArgs to work in a similar pattern. I didn't find examples for adding extra debug specific arguments (say). So here is one.

I also saw in a couple of places (on-line and books), examples such as:

jvmArgs.add( "-DAPPLICATION_LOCATION=City" );
jvmArgs.add( "-DSERVER_HOST=localhost" );

Which as we now understand, do not work.

The use-case I set-out to implement is for the sub-project build.gradle Script to supply missing arguments and/or script specific parameters (e.g. as in the debug run example). It is clear to me that if you want to do this, the script will need to either replace the command line or analyse the args passed-in and then wrinkle-out the defaults by some mechanism.

Hopefully the example will give others more insight.

Solution 3:[3]

Actually this hack is working:

def jvmArgsCopy = jvmArgs
jvmArgsCopy.add("-XX:MaxDirectMemorySize=2g")
jvmArgs = jvmArgsCopy

Solution 4:[4]

And to add to this here it is in Kotlin gradle

    val jvmArgsCopy: ArrayList<String> = jvmArgs as ArrayList<String>
    jvmArgsCopy.add("-Xdebug")
    jvmArgsCopy.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=4000")
    jvmArgs = jvmArgsCopy

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 will
Solution 3 the Tin Man
Solution 4 JPM