Spicy Spring: Reload Classes Spring Boot With Spring Loaded And Gradle Continuous Build
When we develop a Spring Boot application we can hot reload newly compiled classes using Gradle. The bootRun
task of the Spring Boot Gradle plugin has support for Spring Loaded. We must add a dependency to Spring Loaded as a dependency for the classpath
configuration in the buildscript
block. If we now use the bootRun
task everything is ready to reload changed classes. Now we can use the continuous build feature of Gradle to listen for changes in our source files to recompile them. The recompiled classes are then reloaded in the running Spring Boot application started with bootRun
. We start a second Gradle instance with the -t
option for the classes
task. This way when we change a source file it gets recompiled automatically and reloaded.
The following build script shows how we add Spring Loaded:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE"
classpath 'org.springframework:springloaded:1.2.4.RELEASE'
}
}
apply plugin: 'groovy'
apply plugin: 'spring-boot'
jar {
baseName = 'sample'
version = '1.0'
}
repositories {
jcenter()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
compile 'org.codehaus.groovy:groovy-all:2.4.4'
}
Let's also create a very simple Spring Boot application:
package com.mrhaki.sample
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.ResponseBody
@EnableAutoConfiguration
@Controller
class SampleController {
@RequestMapping(value = '/', method = RequestMethod.GET)
@ResponseBody
String sample() {
'Sample controller'
}
static void main(String... args) {
SpringApplication.run(SampleController, args)
}
}
Now we can start a Gradle proces that will recompile class files if the source file changes:
$ gradle -t classes
Continuous build is an incubating feature.
:compileJava UP-TO-DATE
:compileGroovy
:processResources UP-TO-DATE
:classes
BUILD SUCCESSFUL
Total time: 2.847 secs
Waiting for changes to input files of tasks... (ctrl-d to exit)
In another terminal we start the bootRun
task:
$ gradle bootRun
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:findMainClass
:bootRun
objc[16206]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/bin/java and /Library/Java/JavaVirtualMachines/jdk1.8.0\_60.jdk/Contents/Home/jre/lib/libinstrument.dylib. One of the two will be used. Which one is undefined.
. ____ _ __ _ _
/ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _\` | \ \ \ \
/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.2.5.RELEASE)
...
> Building 83% > :bootRun
Written with Gradle 2.7 and Spring Boot 1.2.5.