Search code examples
spring-bootgradlekotlindevtools

How can work DevTools in Kotlin and Gradle project when I guess I tried a lot of solution?


I would like to use DevTools in my Spring Boot web application. I use IntelliJ to it. But it doesn't love me and it doesn't work. I read plenty of documentation about this problem, but probably the solution escaped my attention. Maybe you can help me.

I use Gradle and Kotlin. But I think it shouldn't be a problem. What I tried:

  1. I use devtools dependency in gradle
  2. In Settings -> Build, Execution, Deployment -> Compiler -> I checked in 'Build project automatically'
  3. Ctrl + Shift + A -> Registry... -> I cheked in 'compiler.automake.allow.when.app.running'
  4. In my browser (Chrome) I pressed F12 -> Network -> I checked in 'Disable cache'
  5. I turned off AdBlocker

Here is my Demo:

build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "2.1.8.RELEASE"
    id("io.spring.dependency-management") version "1.0.8.RELEASE"
    kotlin("jvm") version "1.2.71"
    kotlin("plugin.spring") version "1.2.71"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8

val developmentOnly by configurations.creating
configurations {
    runtimeClasspath {
        extendsFrom(developmentOnly)
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    developmentOnly("org.springframework.boot:spring-boot-devtools")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "1.8"
    }
}

com.excample.demo.controller.RestController.kt

package com.example.demo.controller

import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class RestController {

    @RequestMapping("/testDevTools")
    public fun testDev(): String? {
        return "apple"
    }
}

com.excample.demo.DemoApplication.kt

package com.example.demo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
}

And when I start application:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.8.RELEASE)

2019-09-19 15:59:15.727  INFO 6672 --- [  restartedMain] com.example.demo.DemoApplicationKt       : Starting DemoApplicationKt on DESKTOP-QRT95S2 with PID 6672 (started by Baráth Péter in C:\Users\Baráth Péter\OneDrive - Sonrisa Kft\Projects\Demos\devToolsDemo)
2019-09-19 15:59:15.731  INFO 6672 --- [  restartedMain] com.example.demo.DemoApplicationKt       : No active profile set, falling back to default profiles: default
2019-09-19 15:59:15.890  INFO 6672 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2019-09-19 15:59:15.890  INFO 6672 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2019-09-19 15:59:19.376  INFO 6672 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 9090 (http)
2019-09-19 15:59:19.430  INFO 6672 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-09-19 15:59:19.431  INFO 6672 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.24]
2019-09-19 15:59:19.666  INFO 6672 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-09-19 15:59:19.666  INFO 6672 --- [  restartedMain] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 3776 ms
2019-09-19 15:59:20.205  INFO 6672 --- [  restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-09-19 15:59:20.878  WARN 6672 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : Unable to start LiveReload server
2019-09-19 15:59:21.004  INFO 6672 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 9090 (http) with context path ''
2019-09-19 15:59:21.018  INFO 6672 --- [  restartedMain] com.example.demo.DemoApplicationKt       : Started DemoApplicationKt in 6.16 seconds (JVM running for 7.234)
2019-09-19 15:59:45.492  INFO 6672 --- [nio-9090-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-09-19 15:59:45.493  INFO 6672 --- [nio-9090-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-09-19 15:59:45.502  INFO 6672 --- [nio-9090-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms

It contains this line:

2019-09-19 15:59:15.890  INFO 6672 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable

So I don't know what is the problem. Devtools is active. I tried to change apple string in RestController. Then save and refresh the webpage and it didn't change. I am very grateful for any advice.


Solution

  • The setting "Build project automatically" you reference only applies to the IntelliJ's own compiler. If you delegate your build to Gradle, which is the default in newer versions of IntelliJ, it will in fact not build your project automatically.

    The devtools module will only reload classes on recompilation. So you could hit the "Build Project" button whenever you are ready for a reload to trigger a build with Gradle. But as this will also run unit tests and maybe even static code analysis (if you are using that), the turn-around time would still be rather high. You could manually run the classes task with Gradle to compile only classes, but doing this manually is annoying.

    Instead, to continuously compile your classes with Gradle, and only that, run this command in a terminal (assuming you use the wrapper):

    gradlew -t classes

    It will monitor the file system for changes and rerun the classes task on changes. So whenever you make a change to a source file and save it, Gradle will recompile it and the devtools module should pick up the change and reload it.