Gradle
JVM options
bootRun
Java
build configuration

How to pass JVM options from bootRun

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

bootRun starts a Spring Boot application directly from Gradle, which makes it convenient during development. If you need heap settings, system properties, remote debugging, or other JVM-level flags, the important detail is that JVM options belong to the Java process started by bootRun, not to the application arguments passed with --args.

The direct bootRun configuration

bootRun is a JavaExec-style task, so the usual place for JVM flags is jvmArgs:

groovy
1tasks.named("bootRun") {
2    jvmArgs = [
3        "-Xms512m",
4        "-Xmx1024m",
5        "-Dspring.profiles.active=dev"
6    ]
7}

This is the cleanest option when the values are stable for everyone on the project.

These flags affect the JVM that runs your Spring Boot app. They do not modify the Gradle daemon itself, which is a different process with its own settings.

The difference between JVM args and application args

This distinction causes most confusion:

  • JVM args configure the Java runtime
  • application args are what your main method receives

For example:

bash
./gradlew bootRun --args='--server.port=9090'

That passes --server.port=9090 to Spring Boot as an application argument. It does not set -Xmx, -Dfile.encoding, or any other JVM-level flag.

If you need a system property specifically, you can set it as a JVM argument:

groovy
tasks.named("bootRun") {
    jvmArgs = ["-Dexample.mode=local"]
}

and then read it in Java:

java
1public class Main {
2    public static void main(String[] args) {
3        System.out.println(System.getProperty("example.mode"));
4    }
5}

Making the values configurable from the command line

Hard-coding JVM flags is not always ideal. A common Gradle pattern is to read a project property and split it into arguments:

groovy
1tasks.named("bootRun") {
2    if (project.hasProperty("appJvmArgs")) {
3        jvmArgs = project.property("appJvmArgs").toString().split("\\s+")
4    }
5}

Then run:

bash
./gradlew bootRun -PappJvmArgs="-Xmx1g -Dspring.profiles.active=dev"

That keeps the build file flexible without confusing application arguments and JVM arguments.

Debugging support

For quick debugging, Gradle also supports:

bash
./gradlew bootRun --debug-jvm

That starts the application JVM in debug mode and waits for a debugger to attach. It is useful when you need a breakpoint immediately at startup and do not want to maintain a permanent JDWP string in the build file.

If you prefer explicit control, you can still use jvmArgs:

groovy
1tasks.named("bootRun") {
2    jvmArgs = [
3        "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
4    ]
5}

Kotlin DSL example

If your project uses build.gradle.kts, the same idea looks like this:

kotlin
1tasks.named<org.springframework.boot.gradle.tasks.run.BootRun>("bootRun") {
2    jvmArgs = listOf(
3        "-Xms512m",
4        "-Xmx1024m",
5        "-Dspring.profiles.active=dev"
6    )
7}

The concept is identical. Only the syntax changes.

Common Pitfalls

The most common mistake is using --args for JVM settings. That flag passes application arguments only, so something like --args='-Xmx1g' does not do what people expect.

Another mistake is setting org.gradle.jvmargs and assuming it affects the application launched by bootRun. That setting configures the Gradle process, not the Boot application JVM.

People also forget shell quoting when using a project property to carry multiple JVM flags. If the shell splits the string early, Gradle may receive malformed values.

Finally, avoid leaving very aggressive memory settings in the shared build script unless the team actually wants them. Development defaults that work on one machine can be painful on another.

Summary

  • Use bootRun task jvmArgs to pass JVM options to the application process.
  • Use --args only for application arguments, not JVM flags.
  • A project property such as -PappJvmArgs is a practical way to customize values per run.
  • Use --debug-jvm when you want quick startup debugging.
  • Do not confuse the Boot application JVM with the Gradle daemon JVM.

Course illustration
Course illustration

All Rights Reserved.