Java_opts Environment Variable

> From: Marco Antonio [mailto:[hidden email]]
> Subject: Re: How to set JAVA_OPTS variable in tomcat6.0.16
>
> Hi, just need to have the variable JAVA_OPTS exported.
> # export JAVA_OPTS='-Xms1024m -Xmx1024m'
That works for Linux (except for the leading # that turns it into a comment), but says nothing for Windows script or service usage. (The OP didn't bother to tell us the platform being used.)
If running from a Windows script, do the SET JAVA_OPTS before running startup.bat; if using Tomcat as a Windows service, use the Java tab of the tomcat6w.exe program to set up the options.
- Chuck
THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.
---------------------------------------------------------------------
To start a new topic, e-mail: [hidden email]
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

While adjusting some environment variables recently, I came across an odd issue with Docker, Spring Boot and JAVA_OPTS. JAVA_OPTS comes from the Tomcat/Catalina world and when searching for “Docker and javaopts” on Google you’ll find many references to just adding JAVA_OPTS to the Docker environment. After some testing, I found this to be incorrect when running a Spring Boot jar in a Docker container, I’ll explain why and give a solution in this post.

Before I start, let’s setup a basic test environment that prints out the current memory setup so we can test in various situations. I’ve created this repo as a test case and you can refer back to it when needed.

Java_opts Environment Variables

Test Application Setup

Java home environment variables
  1. Use the ESJAVAOPTS environment variable to set heap size. For example, to use 16GB use -e ESJAVAOPTS='-Xms16g -Xmx16g' with docker run. Note that while the default configuration file jvm.options sets a default heap of 1GB, any value you set in ESJAVAOPTS will override it.
  2. Icmdjavaopts You can configure the environment variable ICMDJAVAOPTS to set the Java options such as -Xmx values and system properties. To set a system property, pass the value in the following format.

BWJAVAOPTS='-Dname=value -Dname=value' MASHERYSERVICECONFIG Applications can pass TIBCO Mashery configuration through the MASHERYSERVICECONFIG environment variable. The value of the environment variable is a JSON string with the required TIBCO Mashery configuration.

Looking at the sample code, we have a basic pom file that imports Spring Boot dependencies:

Java_opts Environment Variable

The main application is a single Java file that prints out memory details:

Running this app in IntelliJ with no memory settings will show some basic output with memory settings:

Changing the memory values to -Xmx3g -Xms3g we get a different output:

Example

Java Environment Variables Windows

Now that we have a baseline, let’s move onto the Docker stage.

Docker

The first thing we’ll do is setup a basic Dockerfile similar to the one in the Spring Boot guide. Since the jar will be built in the target folder we grab it from there and place a renamed copy into the container.

To generate the jar, just run maven real quick.

The jar will then be in the target folder ready for building the Docker container.

With the jar and the Dockerfile ready we can build the container from the base folder of the repository.

We can see the newly built image by listing our Docker images.

Java Set Environment Variable Runtime

With our newly built container that will run Spring boot application let’s run it for the first time! Note: I’ll be cutting out some of the output lines to save space since we only care about the memory detail output.

First run looks good. Let’s try setting the JAVA_OPTS as we’re used to!

Woah! The Xmx and Xms settings didn’t have any affect on the Java settings in the container! Something must be wrong here and it’s not immediately obvious if all you search for is for “Docker and javaopts” on Google. Spring Boot is smart enough to handle many passed in environment variables but those are application specific. For example, when you look for a value x.y.z, Spring Boot will look in application.properties by default for x.y.z and in the environment variables for X_Y_Z. Due to this, passing in the environment variable -e X_Y_Z=1234 can be used in your application when using a Docker container. However, since JAVA_OPTS are used by Java and not in the application we run into this problem.

After some searching, I came across the fact that JAVA_OPTS are very specific to Catalina (Tomcat). Looking in the bin folder of a tomcat install you’ll find a shell script that handles passing JAVA_OPTS into the exec lines. With this info, we can now look to change the Dockerfile to adjust for handling passed in environment variables. I named this new Dockerfile ExecDockerfile so I can have both in the same repo.

Java_opts

The change needed to enable JAVA_OPTS is to execute the Java line with an ENTRYPOINT exec command and place the environment variable into the line.

Let’s rebuild the container but specify the new ExecDockerfile specifically using the -f flag.

Let’s run the container again.

Java_opts Environment Variable Vs

Java_opts Environment Variable

Conclusion

Java_options Environment Variable Windows 10

By starting the jar with ENTRYPOINT exec java $JAVA_OPTS, we’ve successfully enabled changing memory settings using Docker environment variables. If you think you’re changing the memory settings currently but are not passing in $JAVA_OPTS into your start line in some fashion, I suggest you look at your Dockerfile config.