How to set JVM arguments when running mvn spring-boot:build-image command in Spring Boot 2.3.0 to generate a docker image?
As of today, you can't set JVM arguments in spring-boot:build-image.
Spring boot build image uses Packeto internally and it accepts following 4 environment variables as mentioned in bellsoft-liberica GitHub.
"BP_JVM_VERSION" : "13.0.1", "BPL_JVM_HEAD_ROOM" : "10","BPL_JVM_LOADED_CLASS_COUNT" : "35", "BPL_JVM_THREAD_COUNT" : "10"
As alternate option, you can pass JVM arguments when you run the image.
docker run -p 8080:8080 --env JAVA_OPTS="-Xmx300m -Xms200m" -t youImageName
If using Kubernetes, you can configure JVM options at deployment level.
spec: containers: - name: yourapp image: image path ports: - containerPort: 8080 env: - name: SPRING_PROFILES_ACTIVE value: "prod" - name: BPL_JVM_HEAD_ROOM value: "2" - name: BPL_JVM_LOADED_CLASS_COUNT value: "35" - name: BPL_JVM_THREAD_COUNT value: "10" - name: JAVA_OPTS value: >- -XX:ReservedCodeCacheSize=40M -XX:MaxMetaspaceSize=60M -Xlog:gc -Xms34m -Xmx40m -Xss256k -XX:MaxRAM=150M
There's a GitHub issue open in Spring boot repository discussing this Failed to change JVM arguments for buildpacked image
Build Back Environment Variables
I tried setting JVM arguments when I started using Spring Boot 2.3 & BuildPacks in November 2020, got nowhere and gave up / put it to one side.
Two weeks ago I picked it up again and purely by chance found this: https://github.com/paketo-buildpacks/environment-variables
Basically, you prefix your environment variable with BPE_APPEND_
and this triggers the Environment Variables Build Pack to append your value to the environment variable.
NB: JAVA_TOOL_OPTIONS
is what you want here, not JAVA_OPTS
.
I needed to attach a Java Agent to monitor our microservices and something like this build.gradle
snippet was what worked:
bootBuildImage { environment = [ 'BPE_DELIM_JAVA_TOOL_OPTIONS' : ' ', 'BPE_APPEND_JAVA_TOOL_OPTIONS' : '-javaagent:my-java-agent.jar' ]}
I used BPE_DELIM_JAVA_TOOL_OPTIONS to make sure a space was added to the existing value of JAVA_TOOL_OPTIONS before my value was appended (the buildpack also allows you to override or prepend to existing value - see their README).
PS: my value was more like '-javaagent:my-java-agent-${some-dynamic-version}.jar'
, so I needed double quotes, but that made it a Gradle String which didn't work so I had to write this instead "-javaagent:my-java-agent-${some-dynamic-version}.jar".toString()
.
As @jeremyt suggests, you can override the value of this property using BPE_OVERRIDE_BPL_JVM_THREAD_COUNT
build variable. Example:
bootBuildImage { environment('BPE_OVERRIDE_BPL_JVM_THREAD_COUNT', '150')}
Sadly, as of now, BPE_DEFAULT_BPL_JVM_THREAD_COUNT
does not work (the value is ignored). The downside of BPE_OVERRIDE_BPL_JVM_THREAD_COUNT
is that it ignores the environment variable set for runtime (in docker run
).