1

I am running a Spring Boot service inside a Docker container and the serivce POM.xml file has this plugin

                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>
                        -Xms1024m
                        -Xmx3096m
                        -XX:+UseConcMarkSweepGC
                        -XX:+HeapDumpOnOutOfMemoryError
                        -XX:HeapDumpPath=logs/heapdump.bin
                        -XX:+PrintGCDetails
                        -Xloggc:logs/data-pipeline-automation-gc.log
                        -XX:NativeMemoryTracking=summary
                        -XX:+CrashOnOutOfMemoryError
                        -XX:ErrorFile=logs/crashDump.log
                    </jvmArguments>
                </configuration>
            </plugin>

I see my service getting an OOM but I don't get the heapdump.bin or the GC logs. This is my configuration in log4j2.xml for springframework logs

            <AppenderRef ref="Console" />
            <AppenderRef ref="RollingFile" />
        </Logger>

So I get the logs created and dumped into /logs folder in the Docker container, but I don't the heapdump.bin file. I am putting it in logs because this is mounted on VM, hence we can access this folder contents from outside access.

Can someone please point out the issue here? I at least need the GC logs to verify the issue.

Deepak Gopal
  • 155
  • 4
  • 18
  • 1
    How do you run it? Do you compile/package it using `mvn package` and just run the JAR in the container or do you compile and run it in the container using `mvn spring-boot:run` or are you using another method? – dan1st Sep 02 '20 at 11:48
  • @dan1st its the former. We compile using `mvn package -DskipTests` and just run teh JAR in the container – Deepak Gopal Sep 02 '20 at 12:01

1 Answers1

3

(JVM) arguments are not part of the JAR.

Eclipse even has a warning indicating this when you try to package an application with arguments to a JAR.

The JVM arguments in the spring-boot-maven-plugin are for running the program using mvn spring-boot:run.

If you want to execute a JAR with JVM arguments, run it by passing those using the command line:

java -XX:+HeapDumpOnOutOfMemoryError -jar yourjar.jar

If you don't want to write those arguments every time you run the program, you could create a wrapper script that just runs the java command with the arguments.

If you really want the jvm arguments to be part of the JAR, you could create another main class (and specify that to be written to the MANIFEST.MF) that just runs itself with the other main class and passes those arguments:

java -XX:+HeapDumpOnOutOfMemoryError -cp yourjar.jar fully.qualified.name.of.Main

However (depending on your needs), the program would need to redirect stdin/stdout, find out the path of the jar, find out the path of the java installation and also pass jvm arguments passed to itself to the program.

dan1st
  • 12,568
  • 8
  • 34
  • 67
  • Maybe adding JAVA_OPTS in the dockerfile and running like this will help `java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /service-1.0.jar`. I'll check this, thanks – Deepak Gopal Sep 02 '20 at 12:41
  • Yes, you can do it using `JAVA_OPTS`, too – dan1st Sep 02 '20 at 12:45