20.2 Automatic restart
Applications that use spring-boot-devtools
will automatically restart whenever files on the classpath change. This can be a useful feature when working in an IDE as it gives a very fast feedback loop for code changes. By default, any entry on the classpath that points to a folder will be monitored for changes. Note that certain resources such as static assets and view templates do not need to restart the application.
Triggering a restart
As DevTools monitors classpath resources, the only way to trigger a restart is to update the classpath. The way in which you cause the classpath to be updated depends on the IDE that you are using. In Eclipse, saving a modified file will cause the classpath to be updated and trigger a restart. In IntelliJ IDEA, building the project (Build → Make Project
) will have the same effect.
Note | |
---|---|
You can also start your application via the supported build plugins (i.e. Maven and Gradle) as long as forking is enabled since DevTools need an isolated application classloader to operate properly. Gradle does this by default and you can force the Maven plugin to fork the process as follows: |
Tip | |
---|---|
Automatic restart works very well when used with LiveReload. See below for details. If you use JRebel automatic restarts will be disabled in favor of dynamic class reloading. Other devtools features (such as LiveReload and property overrides) can still be used. |
Note | |
---|---|
DevTools relies on the application context’s shutdown hook to close it during a restart. It will not work correctly if you have disabled the shutdown hook ( SpringApplication.setRegisterShutdownHook(false) ). |
Note | |
---|---|
When deciding if an entry on the classpath should trigger a restart when it changes, DevTools automatically ignores projects named spring-boot , spring-boot-devtools , spring-boot-autoconfigure , spring-boot-actuator , and spring-boot-starter . |
Restart vs Reload
The restart technology provided by Spring Boot works by using two classloaders. Classes that don’t change (for example, those from third-party jars) are loaded into a base classloader. Classes that you’re actively developing are loaded into a restart classloader. When the application is restarted, the restart classloader is thrown away and a new one is created. This approach means that application restarts are typically much faster than “cold starts” since the base classloader is already available and populated.
If you find that restarts aren’t quick enough for your applications, or you encounter classloading issues, you could consider reloading technologies such as JRebel from ZeroTurnaround. These work by rewriting classes as they are loaded to make them more amenable to reloading. Spring Loaded provides another option, however it doesn’t support as many frameworks and it isn’t commercially supported.
20.2.1 Excluding resources
Certain resources don’t necessarily need to trigger a restart when they are changed. For example, Thymeleaf templates can just be edited in-place. By default changing resources in /META-INF/maven
, /META-INF/resources
,/resources
,/static
,/public
or /templates
will not trigger a restart but will trigger a live reload. If you want to customize these exclusions you can use the spring.devtools.restart.exclude
property. For example, to exclude only /static
and /public
you would set the following:
spring.devtools.restart.exclude=static/**,public/**
Tip | |
---|---|
if you want to keep those defaults and add additional exclusions, use the spring.devtools.restart.additional-exclude property instead. |
20.2.2 Watching additional paths
You may want your application to be restarted or reloaded when you make changes to files that are not on the classpath. To do so, use the spring.devtools.restart.additional-paths
property to configure additional paths to watch for changes. You can use the spring.devtools.restart.exclude
property described above to control whether changes beneath the additional paths will trigger a full restart or just a live reload.
20.2.3 Disabling restart
If you don’t want to use the restart feature you can disable it using the spring.devtools.restart.enabled
property. In most cases you can set this in your application.properties
(this will still initialize the restart classloader but it won’t watch for file changes).
If you need to completely disable restart support, for example, because it doesn’t work with a specific library, you need to set a System
property before calling SpringApplication.run(…)
. For example:
public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(MyApp.class, args); }
20.2.4 Using a trigger file
If you work with an IDE that continuously compiles changed files, you might prefer to trigger restarts only at specific times. To do this you can use a “trigger file”, which is a special file that must be modified when you want to actually trigger a restart check. Changing the file only triggers the check and the restart will only occur if Devtools has detected it has to do something. The trigger file could be updated manually, or via an IDE plugin.
To use a trigger file use the spring.devtools.restart.trigger-file
property.
Tip | |
---|---|
You might want to set spring.devtools.restart.trigger-file as a global setting so that all your projects behave in the same way. |
20.2.5 Customizing the restart classloader
As described in the Restart vs Reload section above, restart functionality is implemented by using two classloaders. For most applications this approach works well, however, sometimes it can cause classloading issues.
By default, any open project in your IDE will be loaded using the “restart” classloader, and any regular .jar
file will be loaded using the “base” classloader. If you work on a multi-module project, and not each module is imported into your IDE, you may need to customize things. To do this you can create a META-INF/spring-devtools.properties
file.
The spring-devtools.properties
file can contain restart.exclude.
and restart.include.
prefixed properties. The include
elements are items that should be pulled up into the “restart” classloader, and the exclude
elements are items that should be pushed down into the “base” classloader. The value of the property is a regex pattern that will be applied to the classpath.
For example:
restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
Note | |
---|---|
All property keys must be unique. As long as a property starts with restart.include. or restart.exclude. it will be considered. |
Tip | |
---|---|
All META-INF/spring-devtools.properties from the classpath will be loaded. You can package files inside your project, or in the libraries that the project consumes. |
20.2.6 Known limitations
Restart functionality does not work well with objects that are deserialized using a standard ObjectInputStream
. If you need to deserialize data, you may need to use Spring’s ConfigurableObjectInputStream
in combination with Thread.currentThread().getContextClassLoader()
.
Unfortunately, several third-party libraries deserialize without considering the context classloader. If you find such a problem, you will need to request a fix with the original authors.