Using Spring Boot Devtools with LiveReload

The (very) short introduction

Using the Spring Boot Devtools can help to increase your development speed. Simply put the corresponding Spring Boot Starter into your application’s dependency tree and voilà—restart, reload, development-optimised settings, … (obviously I’m still in the “wow-that-is-sooooo-amazing”-phase and haven’t had any issues with the devtools so far. Which explains my enthusiasm.).

Nonetheless, including the Spring Boot Devtools in your application will also start a LiveReload-Server:

The spring-boot-devtools module includes an embedded LiveReload server that can be used to trigger a browser refresh when a resource is changed. LiveReload browser extensions are freely available for Chrome, Firefox and Safari from livereload.com.

(Taken from https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-devtools-livereload

And that’s where the fun begins: most of the plugins are outdated; don’t connect to a LiveReload-Server, but rather simply refreshe the current tab in a given interval; or aren’t that popular (in downloads/likes/whatever) that I would want them to be running in my browser.

But there is another solution: a little JavaScript (livereload-js) which could be included in your HTML. This little script connects to a LiveReload-Server and reloads the current page whenever the server tells it to.

The code

Let’s look at a small example using Spring Boot and Thymeleaf:

  1. Create a little (web) starter project. I recommend using Spring Initializr.
  2. Add the Spring Boot Devtools as dependency. If you are using Maven, now your pom.xml might look like (excerpt):
    ...
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
    ...
    
  3. Configure the application and the embedded tomcat (application.properties):
    # ----------------------------------------
    # SPRING BOOT // SPRING RESOURCES HANDLING (ResourceProperties)
    # ----------------------------------------
    #
    # somehow this isn't set by devtools, but needed to get changes delivered on some resources like css (without restarting the application)
    spring.resources.chain.cache=false
        
    # ----------------------------------------
    # SPRING BOOT // EMBEDDED SERVER CONFIGURATION (ServerProperties)
    # ----------------------------------------
    #
    # disabling tls makes this example a little easier. don't let this settings sneak into production!
    server.port=8080
    server.ssl.enabled=false
    
    # ----------------------------------------
    # SPRING BOOT // DEVTOOLS (DevToolsProperties)
    # ----------------------------------------
    #
    # this is not a property defined by Spring Boot (note the "foobar")
    foobar.devtools.livereload.include-js=true
    
  4. Download the LiveReload script livereload.js and place it into
    src/main/resources/static/js
    
  5. Include the script in your Thymeleaf template:
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Spring Boot Devtools with livereload.js</title>
    </head>
    <body>
        <h1>Hello World</h1>
        <script
            th:with="host=${#request.getServerName()},port=${@environment.getProperty('spring.devtools.livereload.port')}"
            th:src="@{js/livereload.js(host=${host},port=${port == null}? 35729 : ${port},v=2.2.2)}"
            th:if="${@environment.getProperty('foobar.devtools.livereload.include-js')}"></script>
    </body>
    </html>
    
  6. Start your application using the embedded Tomcat. Which means: use the main-method in your Application.java. The devtools will not work if your application:
    • is packed as a war (and deployed on a Servlet Container),
    • is packed as a jar (and started by java -jar),
    • is repacked by the Spring Boot Maven Plugin or
    • (insert another point I forgot/did not know here).
  7. Open your application in your browser.
  8. Now change the Thymeleaf template by inserting something like “Hello Devtools”. You should see your changes immediately.

Some remarks

  • In a real world application you wouldn’t add those settings/properties in step 3 in your application.properties. Consider e.g. using an application-devel.properties and activate a Spring Profile “devel” (by using -Dspring.profiles.active=default,devel).
  • If reloading doesn’t work, open your browser’s devtools (ah—another one). Maybe it’s just a resource, which couldn’t be loaded. Or the connection to the LiveReload-Server couldn’t be established. The browser-devtool’s console will list this.

Rolf Engelhard

 

Leave a Reply

Required fields are marked *.