We recently upgraded gradle version in our project from 7.1.x to 7.3.x. We observed that we are no longer able to connect visualvm java(11) application running in kubernetes. Port-forward works but when visualvm connection is opened, port-forwarding stops. We found few blogs indicating a CVE fix in 7.2.x which says "Gradle 7.2 start script stopped expanding environment variables passed inside JAVA_OPTS".
https://github.com/gradle/gradle/issues/18170
https://github.com/gradle/gradle/security/advisories/GHSA-6j2p-252f-7mw8
Application gradle scripts:
We pass jvm parameters through gradle and artifacts is passed as entrypoint to docker image. What is the right way to pass jvm parameters after 7.2.x?
ext.getJvmArgs = { jmxPort, jdwpPort, initialRamPercentage = 50.0, maxRamPercentage = 70.0 ->
return ["-XX:InitialRAMPercentage=$initialRamPercentage",
"-XX:MaxRAMPercentage=$maxRamPercentage",
"-XX:+UseStringDeduplication",
// Force G1GC as the GC collector. In a container environment, GC is selected by docker based on CPU and Memory.
"-XX:+UseG1GC",
"-Duser.timezone=\"UTC\"",
"-Dcom.sun.management.jmxremote",
"-Dcom.sun.management.jmxremote.authenticate=false",
"-Dcom.sun.management.jmxremote.ssl=false",
"-Dcom.sun.management.jmxremote.local.only=false",
"-Dcom.sun.management.jmxremote.port=$jmxPort",
"-Dcom.sun.management.jmxremote.rmi.port=$jmxPort"]
}
application {
int jmxPort = 2609
int jdwpPort = 2611
float initialRamPercentage = 30.0
float maxRamPercentage = 60.0
applicationDefaultJvmArgs = project.getJvmArgs(jmxPort, jdwpPort, initialRamPercentage, maxRamPercentage) + ['-XX:ErrorFile=/tmp/hs_err_pid%p.log']
getMainClass().set('com.xxx.yyy.AbcMain')
}
task customScript(type: CreateStartScripts) {
mainClass = "com.xxx.yyy.XyzMain"
applicationName = "xyz"
int jmxPort = 2609
int jdwpPort = 2611
float initialRamPercentage = 30.0
float maxRamPercentage = 60.0
defaultJvmOpts = project.getJvmArgs(jmxPort, jdwpPort, initialRamPercentage, maxRamPercentage) + ['-XX:ErrorFile=/tmp/hs_err_pid%p.log']
outputDir = new File(project.buildDir, 'scripts')
classpath = jar.outputs.files + configurations.runtimeClasspath
}
applicationDistribution.into("bin") {
from(customScript)
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
Finally after spending good amount of time in debuging this, it was special character in parameters which was somehow working with gradle 7.1 and earlier. After gradle 7.2, all parameters inclduing user timezone was getting truncated.
"-Duser.timezone=\"UTC\""
After I removed double quotes and backslash, I could connect to visualvm and see all jvm parameters showing up in defaultJVmOpts
Correct way of passing timezone:
"-Duser.timezone=UTC"