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:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
dependencies {
developmentOnly("org.springframework.boot:spring- boot-devtools")
}
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
.
developmentOnly
configuration in Gradle (as shown above), this will prevent devtools from being transitively applied to other modules using your project.
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 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
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.
SpringApplication.setRegisterShutdownHook(false)
).
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.
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:
spring.devtools.restart.log-condition-evaluation-delta=false
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:
spring.devtools.restart.exclude=static/**,public/**
spring:
devtools:
restart:
exclude: "static/**,public/**"
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:
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);
}
}
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.
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:
spring.devtools.restart.trigger-file=.reloadtrigger
spring:
devtools:
restart:
trigger-file: ".reloadtrigger "
Restart will now only occur when updating src/main/resources/.reloadtrigger
.
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 jar
file 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:
restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\\.]+\\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\\.]+\ \.jar
restart:
exclude:
companycommonlibs: "/mycorp-common-[\\w\\d-\\.]+\\.jar"
include:
projectcommon: "/mycorp-myproj-[\\w\\d-\\.]+\\.jar "
restart.include.
or
restart.exclude.
, then it is taken into account.
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
.
Global Settings
You can configure devtools global settings by adding any of the following files to the $HOME/.config/spring-boot
directory:
spring-boot-devtools.properties
spring-boot-devtools.yaml
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:
spring.devtools.restart.trigger-file=.reloadtrigger
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.
$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:
spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period= 1s
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.
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 theRun
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
inProgram 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
spring.devtools.remote.secret
property and passes it to the server for authentication.
https://
as a connection protocol so that traffic is encrypted and passwords cannot be intercepted.
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 .
GO TO FULL VERSION