Spring Boot DevTools: Automatic Restart and Development Settings

Set up Spring Boot DevTools, observe a classpath restart after compilation, and distinguish static-resource changes from a packaged JAR run. Verified with Spring Boot 4.1.2.

spring boot logo

Spring Boot DevTools watches development classpath directories and restarts the application when compiled classes change. Editing Java source alone does not trigger a restart: the IDE or build tool must update the compiled class. The examples use Spring Boot 4.1.2 and a small endpoint to make that difference visible.

1. Add DevTools to the Project

Add spring-boot-devtools as an optional Maven dependency alongside the web MVC starter used by this sample. The optional setting keeps DevTools from becoming a transitive dependency of another project that depends on this one. The Spring Boot Maven plugin also excludes DevTools from the repackaged JAR by default. The complete build file uses the Spring Boot starter parent to manage versions.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webmvc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

For Gradle, use the developmentOnly configuration:

dependencies {
    developmentOnly("org.springframework.boot:spring-boot-devtools")
}

The Spring Boot DevTools reference gives both dependency forms. Add a web starter separately if the application exposes HTTP endpoints; DevTools itself does not supply Spring MVC.

2. Run an Application That Shows the Change

Our sample serves a catalog status. The controller returns a version marker so the response changes visibly after recompilation. The main class starts the application:

package com.howtodoinjava.devtools;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DevtoolsApplication {
    public static void main(String[] args) {
        SpringApplication.run(DevtoolsApplication.class, args);
    }
}

The controller is in the same package, so component scanning finds it:

package com.howtodoinjava.devtools;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class StatusController {
    @GetMapping("/status")
    public String status() {
        return "Catalog ready v1";
    }
}

Start the application with the Maven plugin. This runs from project classpath directories, which DevTools monitors:

mvn spring-boot:run

In another terminal, request the endpoint. The first response establishes the value before the edit:

curl http://localhost:8080/status
# Catalog ready v1

3. Recompile to Trigger Automatic Restart

Change the return value in StatusController from Catalog ready v1 to Catalog ready v2, then update the classpath. In IntelliJ IDEA, choose Build > Build Project. From a separate terminal, Maven can do the same job:

mvn compile

DevTools notices the changed compiled class and restarts the application context. In the running application’s log, look for a restart message similar to this one; the change count and timing depend on the build:

Restarting due to 2 class path changes
Started DevtoolsApplication

Request the same endpoint again:

curl http://localhost:8080/status
# Catalog ready v2

We ran this sequence with Spring Boot 4.1.2. The response changed only after mvn compile updated the classpath. DevTools uses separate base and restart classloaders so it can replace application classes without starting a completely new JVM. It still restarts the application context; it is not Java hot-swap of one method body.

4. Change a Static Resource Without Restarting the Application

DevTools treats a static file differently from a compiled Java class. The sample includes src/main/resources/static/note.txt:

Catalog status page v1

While the app runs, edit that file to say Catalog status page v2 and copy resources to the output directory:

mvn resources:resources
curl http://localhost:8080/note.txt
# Catalog status page v2

Paths such as static and templates are excluded from full restarts by default. The file can be served with new content after the classpath resource changes, without restarting the application context. A browser may still need a refresh to display it. DevTools includes a LiveReload server, but LiveReload is deprecated as of Spring Boot 4.1.0; this example does not depend on a browser extension or that feature.

5. Choose Which Changes Trigger Restart

The default resource exclusions avoid a full restart for common static and template directories. If your project has another generated-resource directory, add it to the defaults rather than replacing the entire list:

spring.devtools.restart.additional-exclude=generated/**

Use spring.devtools.restart.exclude only when you intend to replace the default exclusion patterns. To watch a path outside the classpath, set additional-paths. The effect of a change in that path depends on the exclusion rules:

spring.devtools.restart.additional-paths=../shared-config

For a large build that changes many files, a trigger file lets you decide when DevTools checks for a restart. Create the named file on the classpath and update it after the build finishes:

spring.devtools.restart.trigger-file=.reloadtrigger

These settings go in src/main/resources/application.properties. The relative paths are interpreted for the running project, so verify that the named directory or trigger file exists where the application actually runs.

6. Check the Packaged JAR Boundary

The Maven plugin excludes the optional DevTools dependency from the repackaged archive by default. Build and run the JAR to see the production-style launch path:

mvn package
java -jar target/spring-boot-devtools-demo-1.0.0.jar

The endpoint still works, but DevTools automatic restart is not active for this fully packaged run. Recompiling a source file in the project does not replace a class inside the already running JAR. Stop the process, rebuild the JAR, and start the new artifact to use the changed code. Do not enable DevTools in a production deployment; its remote capabilities and development defaults do not belong there.

7. When a Change Does Not Restart the App

First, check the response before and after compilation rather than assuming the editor saved a compiled class. This sequence distinguishes a stale build from a watcher problem:

mvn compile
curl http://localhost:8080/status

If the response remains v1, inspect whether target/classes contains the updated class and whether the running command is mvn spring-boot:run rather than java -jar. Check the DevTools startup log for the restart classloader. If the app has disabled Spring’s shutdown hook, DevTools cannot close the context correctly during restart. Some multi-module applications also need classloader customization; use the official DevTools guide when that specific failure appears.

8. FAQs

8.1. Does saving a Java file always restart Spring Boot?

No. DevTools watches the classpath, not the source editor. An IDE build or mvn compile must write the updated class before DevTools can detect it. A save can appear to restart automatically in an IDE that compiles on save.

8.2. Why does the application restart but my browser stay unchanged?

Application restart and browser refresh are separate. DevTools restarts the Spring context after compiled-class changes. Refresh the browser or repeat the HTTP request to see the new response. The optional LiveReload feature can refresh a browser with an extension, but it is deprecated in Spring Boot 4.1.

9. Conclusion

Use spring-boot-devtools for the local edit, compile, and restart loop. If a Java change is not visible, check whether it reached the running classpath before changing restart settings. Keep DevTools out of the packaged production application.

Happy Learning!

The complete runnable example on GitHub contains the Maven build, application, controller, and static file.

Leave a Comment

  1. How to apply devtool dependencies if we use explicit Tomcat. I applied devtool dependencies in parent pom, still no luck.

  2. Is the devtools library can able to detect XML files also,when we do any modifications in XML file.with out restart the server.

  3. Can you please describe the restart-trigger.txt in detailed….? means what are the parameters used to and what are the allowed params and values…? Thanks

Comments are closed.

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.