Spring Boot Live Reload with Gradle and Intellij 15

I've been diving into Spring Boot lately. As a big fan of Grails and knowing that Grails 3 uses Spring Boot I wanted to become more familiar with the underlying technology. So far, I'm impressed. Spring has come a long way since the days of XML configuration hell.

One of the features that I love about Grails is the Live Reload feature. Grails 3 uses Spring's Spring Loaded; this same technology can be used in your Spring Boot applications. Unfortunately, the documentation isn't overly clear on how to wire everything up. Especially if you're using a Gradle build and Intellij.

Gradle

The Gradle build file requires minor changes to support Live Reload. And these changes are pretty well spelled out in the documentation but I'll repeat them here for clarity.

buildscript {  
  ext {
    springBootVersion = '1.3.0.RELEASE'
  }
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    classpath 'org.springframework:springloaded:1.2.4.RELEASE'
  }
}

Note the springloaded classpath entry:
org.springframework:springloaded:1.2.4.RELEASE

As of this writing, it is important to use 1.2.4.RELEASE. The documentation still refers to 1.2.0 and this will not work. Next, the Gradle build needs to tell IntelliJ where to build files to because the default path will not work. So add the following:

idea {  
  module {
    inheritOutputDirs = false
    outputDir = file("$buildDir/classes/main/")
  }
}

This part is important - Make sure you run the following command:

> gradle idea

This will make sure IntelliJ gets updated with the changes. You'll also want to refresh the Gradle project in IntelliJ so the classpath gets updated with springloaded.

IntelliJ

Next, we need to tell IntelliJ to automatically make/compile files that have changed. Eclipse does this by default but IntelliJ doesn't. I learned this tip from Dan Vega's Spring Boot course on Udemy. Definitely worth checking out. It has been a great course thus far.

First, check the Make project automatically setting in IntelliJ's preferences:

Next, go to Help -> Find Action

Search for Regsitry and hit enter:

Make sure that compiler.automake.allow.when.app.running is checked.

Running Your App

Originally, I was using IntelliJ's built in Spring Boot run configuration to run/debug my app. This uses the Spring Boot CLI. However, for springloaded to work, you'll need to run a Gradle task instead. From the command line you can simply execute:

> gradle bootRun

Or you can create a Gradle run configuration in IntelliJ to run the same command. Doing this allows you to run in debug mode so you can get all your breakpoint goodness.

And that's pretty much it. Now, when you make changes to your Java or Groovy code, springloaded does its magic and you'll see the changes almost immediately, with one caveat: It doesn't recognize changes in annotations.

For example, say you had the following:

@RequestMapping(method = RequestMethod.GET)
def submissions(@RequestParam(value='name', required = false, defaultValue = 'Gregg') String name, Model model) {  
  model.addAttribute('name', name)
  return 'submissions'
}

If I change defaultValue = Gregg to defaultValue = John, this doesn't get picked up by springloaded. I'm not sure why just yet. I'm still researching it. If anyone has any insight into this I'd be happy to know about it.