Spring Boot contains an additional set of tools that can make the application development process a little more enjoyable. The spring-boot-devtools module can be added to any project to provide additional functionality during development. To implement devtools support, add a module dependency to your build, as shown in the following listings for Maven and Gradle:

Maven
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
    </dependency>
</dependencies>
Gradle
dependencies {
    developmentOnly("org.springframework.boot:spring- boot-devtools")
}
The development tools are automatically deactivated when running a fully packaged application. If your application runs via java -jar or a custom class loader, then it is considered a "production application". You can control this operating logic using the spring.devtools.restart.enabled system property. To enable devtools regardless of the class loader used to start the application, set the system property -Dspring.devtools.restart.enabled=true. This should not be done in a production environment where running devtools poses a security risk. To disable devtools, exclude the dependency or set the system property -Dspring.devtools.restart.enabled=false.
If checked dependency in Maven as optional or use the developmentOnly configuration in Gradle (as shown above), this will prevent devtools from being transitively applied to other modules using your project.
Repackaged archives do not contain devtools by default. If you want to use a specific devtools remote feature, you need to include it. When using the Maven plugin, set the excludeDevtools property to false. When using the Gradle plugin, configure the classpath for the task to contain the developmentOnly configuration.

Diagnosing class loading problems

Restart functionality has been implemented using two class loaders. For most applications this approach works well. However, it can sometimes lead to class loading problems, especially in multi-module projects.

To diagnose whether class loading problems are actually caused by devtools and its two class loaders, try disabling restart. If this solves your problems, set the class loader restart to cover your entire project.

Default properties

Some libraries supported by Spring Boot use caches to improve performance. For example, template engines cache compiled templates to avoid repeatedly parsing template files. Additionally, Spring MVC can add HTTP caching headers to responses when processing static resources.

While caching is very useful in a production environment, it can be counterproductive during development, preventing you from seeing changes that have just been made included in the application. For this reason, spring-boot-devtools disables caching settings by default.

Cache settings are typically configured using settings in the application.properties file. For example, Thymeleaf provides a spring.thymeleaf.cache property. Instead of setting these properties manually, the spring-boot-devtools module automatically applies the appropriate configuration during development.

The following table lists all the applied properties:

Name Default value

server.error.include-binding-errors

always

server.error.include-message

always

server.error.include-stacktrace

always

server.servlet.jsp.init-parameters.development

true

server.servlet.session.persistent

true

spring.freemarker.cache

false

spring.graphql.graphiql.enabled

true

spring.groovy.template.cache

false

spring.h2.console.enabled

true

spring.mustache.servlet.cache

false

spring.mvc.log-resolved-exception

true

spring.reactor.debug

true

spring.template.provider.cache

false

spring.thymeleaf.cache

false

spring.web.resources.cache.period

0

spring.web.resources.chain.cache

false

If you do not want the default settings to be applied, you can set spring.devtools.add-properties to false in the file application.properties.

Because development of Spring MVC and Spring WebFlux applications requires more information about web requests, the development tools suggest enabling DEBUG logging for web-logging groups. This will give information about the incoming request, which handler is processing it, the result of the response, and other details. If you want to log all request details (including potentially sensitive information), you can enable the spring.mvc.log-request-details or spring.codec.log-request-details.

Automatic restart

Applications using spring-boot-devtools are automatically restarted when files in the classpath are changed. This can be a useful feature when working in an IDE as it provides very fast feedback for making changes to the code. By default, any entry in the classpath that points to a directory is monitored for changes. Please note that some resources, such as static content and view templates, do not require an application restart.

Initiating a restart

Because DevTools tracks resources in the classpath, the only way to initiate a restart is by updating the classpath. Regardless of whether you use the IDE or one of the build plugins, changed files must be recompiled to trigger a restart. How the classpath is updated depends on the tool used:

  • In Eclipse, saving a changed file updates the classpath and triggers a restart.

  • In IntelliJ IDEA building a project (Build +→+ Build Project) has the same effect.

  • If using a build plugin, run mvn compile for Maven or gradle build for Gradle will trigger a restart.

If the restart is done using Maven or Gradle using a build plugin, then you need to leave the value of forking set to enabled. If you disable forking, the application's isolated class loader used by devtools will not be created and restarting will not work as expected.
Automatic restart performs very well when used with LiveReload. If you are using JRebel, automatic reloads are disabled in favor of dynamic class reloading. Other devtools features (such as LiveReload and property overriding) will still be usable.
DevTools uses an application context termination hook to close it during restart. It will not work correctly if the shutdown hook is disabled (SpringApplication.setRegisterShutdownHook(false)).
DevTools needs to configure the loader ResourceLoader used by ApplicationContext. If your application already provides such a loader, it will be wrapped. Direct overriding of the getResource method on ApplicationContext is not supported.
Automatic restart is not supported when using a binding via AspectJ.
Restart and reload

The restart technology provided by Spring Boot works using two class loaders. Classes that do not change (for example, classes from third-party jar files) are loaded into the main class loader. Classes that are actively developed are loaded into the restart classloader. If the application is restarted, the restartclass loader is used once and a new one is created. This approach means that restarting the application is usually much faster than a cold start because the mainclass loader is already available and full.

If you find that the restart is not fast enough to of your applications or are experiencing class loading issues, you may want to check out reloading technologies like JRebel from ZeroTurnaround . They work by rewriting classes as they are loaded to make them easier to load again.

Log changes to state calculation

By default every time When the application is restarted, a report is logged showing the state calculation delta. The report shows changes to your application's autoconfiguration as you make changes, such as adding or removing beans and setting configuration properties.

To disable reporting logging, set the following property:

Properties
spring.devtools.restart.log-condition-evaluation-delta=false
Yaml
spring:
    devtools:
        restart:
            log-condition-evaluation-delta: false

Resource exclusion

Some resources do not necessarily need to trigger a reload when they change. For example, Thymeleaf templates can be edited in the same place. By default, changing resources in /META-INF/maven, /META-INF/resources, /resources, /static, /public or /templates does not trigger a restart, but does trigger a real-time reload. If you want to configure these exceptions, you can use the spring.devtools.restart.exclude property. For example, to exclude only /static and /public, you would set the following property:

Properties
spring.devtools.restart.exclude=static/**,public/**
Yaml
spring:
    devtools:
        restart:
            exclude: "static/**,public/**"
If you want to keep these default values ​​and add additional exceptions, use the spring.devtools.restart.additional-exclude property .

Tracking additional paths

You may want the application to restart or reload after making changes to files that are not in the classpath. To do this, use the spring.devtools.restart.additional-paths property to configure additional paths for change tracking. You can use the spring.devtools.restart.exclude property to control whether changes to additional paths will trigger a full restart or a real-time restart.

Disabling restart

If you do not need to use the restart feature, you can disable it using the spring.devtools.restart.enabled property. In most cases, you can set this property in the application.properties file (this will still initialize the restarting classloader, but file changes will not be tracked).

If required completely disable restart support (for example, because it does not work with a certain library), then before calling SpringApplication.run(…​) you need to set the System for spring.devtools.restart.enabled to false, as shown in the following example:

Java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(MyApplication.class, args);
    }
}
Kotlin

import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication
object MyApplication {
    @JvmStatic
    fun main(args: Array<String>) {
        System.setProperty("spring.devtools.restart.enabled", "false")
        SpringApplication.run(MyApplication::class.java, *args)
    }
}

Using a trigger file

If you are working with an IDE that constantly compiles files that change, you may prefer to trigger a reload only at certain times. To do this, you can use a "trigger file", which is a specialized file that needs to be modified if you actually want to trigger the restart check.

Any update file triggers a check, but the restart only occurs if Devtools detects that it needs to do something.

To use a trigger file, set the property spring.devtools.restart.trigger-file to the name (excluding path) of your trigger file. The trigger file should be somewhere in your classpath.

For example, if you have a project with the following structure:

src
+- main
    +- resources
        +- .reloadtrigger

Then the property of your trigger-file will be like this:

Properties
spring.devtools.restart.trigger-file=.reloadtrigger
Yaml
spring:
    devtools:
        restart:
            trigger-file: ".reloadtrigger "

Restart will now only occur when updating src/main/resources/.reloadtrigger.

You may want to set spring.devtools.restart.trigger-file as a global setting so that all your projects have the same logic.

Some IDEs have features that eliminate the need to manually update the trigger file. Spring Tools for Eclipse and IntelliJ IDEA (Ultimate Edition) has such support tools. In Spring Tools, you can use the "reload" button from the console view (assuming your trigger-file is named .reloadtrigger). For IntelliJ IDEA, you can follow instructions in the relevant documentation.

Configuring a restarting class loader

The restart functionality is implemented through two class loaders. If any problems arise, you may need to configure what is loaded with which class loader.

By default, any open project in your IDE is loaded with a "restart" class loader, and any regular. The jarfile is loaded with the "main" class loader. The same is true if mvn spring-boot:run or gradle bootRun is used: a project containing the @SpringBootApplication annotation is loaded with "restart" the class loader, and everything else with the "main" class loader.

You can tell Spring Boot to load project components with a different class loader by creating a file META-INF/spring-devtools.properties. The spring-devtools.properties file may contain properties with the prefixes restart.exclude and restart.include. include elements are components that need to be pushed up into the "restarting" classloader, and exclude elements are elements that need to be pushed down into the "main" classloader. The property value is a regular expression pattern that is applied to the classpath, as shown in the following example:

Properties
restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\\.]+\\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\\.]+\ \.jar
Yaml
restart:
    exclude:
        companycommonlibs: "/mycorp-common-[\\w\\d-\\.]+\\.jar"
    include:
        projectcommon: "/mycorp-myproj-[\\w\\d-\\.]+\\.jar "
All property keys must be unique. If a property begins with restart.include. or restart.exclude., then it is taken into account.
Loads all META-INF/spring-devtools.properties from the classpath. You can package files within your project or in libraries that the project uses.

Known limitations

The restart functionality does not work very well with objects that are deserialized using the standard ObjectInputStream. If you need to deserialize data, you may need to use ConfigurableObjectInputStream from Spring in combination with Thread.currentThread().getContextClassLoader().

Unfortunately, some Third-party libraries deserialize without taking into account the context class loader. If you encounter such a problem, you will need to request a fix from the creators.

LiveReload

The spring-boot-devtools module contains a built-in LiveReload server, which can be used to trigger a browser refresh when a resource changes. LiveReload browser extensions for Chrome, Firefox and Safari are freely available at livereload.com.

If you do not need to start the LiveReload server when running the application, you can set the spring.devtools.livereload.enabled property to false.

Only one LiveReload server can be running at a time. Before starting the application, make sure that no other LiveReload servers are running. If you run multiple applications from the IDE, only the first one will support LiveReload.
To trigger LiveReload when a file changes, automatic restart must be enabled.

Global Settings

You can configure devtools global settings by adding any of the following files to the $HOME/.config/spring-boot directory:

  1. spring-boot-devtools.properties

  2. spring-boot-devtools.yaml

  3. spring-boot-devtools.yml

Any properties added to These files apply to all Spring Boot applications on your machine that use devtools. For example, to configure restart to always use a trigger file, you would add the following property to the spring-boot-devtools file:

Properties
spring.devtools.restart.trigger-file=.reloadtrigger
Yaml
spring:
    devtools:
        restart:
            trigger-file: ".reloadtrigger"

Default $HOME is the user's home directory. To configure this location, set the SPRING_DEVTOOLS_HOME environment variable or the spring.devtools.home system property.

If no devtools configuration files are found in $HOME/.config/spring-boot, the root of the $HOME directory will be searched for the presence of a file .spring-boot-devtools.properties. This will allow the global devtools configuration to be shared with applications that run on an older version of Spring Boot that does not support the $HOME/.config/spring-boot location.

Profiles are not supported in properties/yaml files for devtools.

Any profiles enabled in .spring-boot-devtools.properties , will not affect the download of files associated with a specific profile. Profile-specific file names (like spring-boot-devtools-<profile>.properties) and spring.config.activate.on-profile documents in YAML files and Properties are not supported.

Configuring a file system watcher

FileSystemWatcher is working by polling for class changes at certain time intervals and then waiting for a predefined period of inactivity to ensure that there are no more changes. Because Spring Boot relies entirely on the IDE to compile and copy files to a location where Spring Boot can read them, you may experience some changes not being reflected when you restart your application using devtools. If you experience problems like this consistently, try increasing the spring.devtools.restart.poll-interval and spring.devtools.restart.quiet-period settings to values ​​that match your development environment:

Properties
spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period= 1s
Yaml
spring:
    devtools:
        restart:
            poll-interval : "2s"
            quiet-period: "1s"

Monitored classpath directories are now polled every 2 seconds for changes, and a 1 second quiet period is observed, to ensure that there are no additional changes to classes.

Remote applications

Spring Boot developer tools are not limited to local development. You can also use several features when running applications remotely. Remote work support tools are optional because their activation may pose a security risk. They should only be enabled when working on a trusted network or if protected by SSL. If none of these options are available, you should not use the remote support tools for DevTools. Under no circumstances should you enable support tools during a production deployment.

To enable support, you must ensure that devtools is included in the repackaged archive, as shown in the following listing:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludeDevtools>false</excludeDevtools>
            </configuration>
        </plugin>
    </plugins>
</build>

Then you need to set the spring.devtools.remote.secret property. Like any important password or sensitive information, the value must be unique and strong so that it cannot be guessed or brute-forced.

The devtools remote support tools are provided in two parts: a server-side endpoint, connection receiver, and a client application that you run in your IDE. The server component is automatically activated if the spring.devtools.remote.secret property is set. The client component must be started manually.

Remote work with devtools is not supported for Spring WebFlux applications.

Running a remote client application

The remote client application is designed to run from your IDE. You must execute org.springframework.boot.devtools.RemoteSpringApplication with the same classpath as the remote project you are connecting to. The only required argument to the application is the remote URL to which it connects.

For example, if you are using Eclipse or Spring Tools and have a project named my-app that is deployed to Cloud Foundry, you need to do the following:

  • Select Run Configurations…​ from the Run menu.

  • Create a new "launch configuration" Java Application.

  • Find the project my-app.

  • Use org.springframework.boot.devtools.RemoteSpringApplication as the main class.

  • Add https://myapp.cfapps.io in Program arguments (or whatever your remote access URL is).

The running remote client might look like this:

 .   ____          _                                              __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _          ___               _      \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` |        | _ \___ _ __  ___| |_ ___ \ \ \ \
 \\/  ___)| |_)| | | | | || (_| []::::::[]   / -_) '  \/ _ \  _/ -_) ) ) ) )
  '  |____| .__|_| |_|_| |_\__, |        |_|_\___|_|_|_\___/\__\___|/ / / /
 =========|_|==============|___/===================================/_/_/_/
 :: Spring Boot Remote ::  (v2.7.5)
2022-10-20 12:40:15.175  INFO 16215 --- [           main] o.s.b.devtools.RemoteSpringApplication   : Starting RemoteSpringApplication v2.7.5 using Java 1.8.0_345 on myhost with PID 16215 (/Users/myuser/.m2/repository/org/springframework/boot/spring-boot-devtools/2.7.5/spring-boot-devtools-2.7.5.jar started by myuser in /opt/apps/)
2022-10-20 12:40:15.182  INFO 16215 --- [           main] o.s.b.devtools.RemoteSpringApplication   : No active profile set, falling back to 1 default profile: "default"
2022-10-20 12:40:15.913  INFO 16215 --- [           main] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2022-10-20 12:40:15.946  INFO 16215 --- [           main] o.s.b.devtools.RemoteSpringApplication   : Started RemoteSpri        
Because the remote client uses the same classpath as the actual application, it can directly read the application's properties. This reads the spring.devtools.remote.secret property and passes it to the server for authentication.
It is always recommended to use https:// as a connection protocol so that traffic is encrypted and passwords cannot be intercepted.
If you need to use a proxy to access a remote application, configure the properties spring.devtools.remote.proxy.host and spring.devtools.remote.proxy.port.

Remote update

The remote client monitors changes to your application's classpath in the same way that a local restart program does. Any updated resource is passed to the remote application and (if required) triggers a restart. This can be useful if you are repeating a function that uses a cloud service that is not available locally. In general, a remote upgrade and reboot is much faster than a complete rebuild and deployment.

In a slow development environment, it may be that the idle period is insufficient and changes to classes may be broken up into batches. The server will restart after downloading the first batch of class changes. The next package cannot be sent to the application because the server is being restarted.

This typically results in a warning in the RemoteSpringApplication logs that some classes could not be loaded and then retrying . But this can also result in inconsistent application code and the inability to restart after downloading the first batch of changes. If you experience problems like this consistently, try increasing the spring.devtools.restart.poll-interval and spring.devtools.restart.quiet-period settings to values ​​that match your development environment .

Files are tracked only while the remote client is running. If you change a file before the remote client is running, it will not be transferred to the remote server.