我们最近将项目中的 gradle 版本从 7.1.x 升级到 7.3.x。我们发现我们无法再连接在 kubernetes 中运行的 VisualVM java(11) 应用程序。端口转发有效,但当打开 VisualVM 连接时,端口转发停止。 我们发现很少有博客指出 7.2.x 中的 CVE 修复,其中显示“Gradle 7.2 启动脚本停止扩展在 JAVA_OPTS 内传递的环境变量”。
https://github.com/gradle/gradle/issues/18170
https://github.com/gradle/gradle/security/advisories/GHSA-6j2p-252f-7mw8
应用程序gradle脚本:
我们通过 gradle 传递 jvm 参数,并将工件作为 docker 镜像的入口点传递。 7.2.x之后传递jvm参数的正确方法是什么?
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
}
最后,在花费了大量时间进行调试之后,参数中的特殊字符在某种程度上可以与 gradle 7.1 及更早版本一起使用。在 gradle 7.2 之后,包括用户时区在内的所有参数都被截断。
"-Duser.timezone=\"UTC\""
删除双引号和反斜杠后,我可以连接到 VisualVM 并查看默认JVmOpts 中显示的所有 jvm 参数
传递时区的正确方法:
"-Duser.timezone=UTC"