Roland Ewald

Software Engineer · Researcher



Spring Boot projects in IntelliJ IDEA

2018-04-01


Problem

Setting up gradle-based Spring Boot projects in IntelliJ IDEA is tricky.

A good development experience means it is easy to

  • start any @SpringBootApplication (via its main method)

  • start any test case, including integration tests using @SpringBootTest etc.

Since local development machines cannot reach all remote services and often rely on mock-up beans for those (which, of course, are part of the test code), and also rely on .properties files for application profiles such as test or dev (which, of course, are part of the test resources), you may run into trouble when trying to run applications and tests in IDEA.

This is because IDEA does not allow simple ad-hoc modifications to the classpath, and at the same time will override all manually changed dependencies whenever you touch a build.gradle file and will also not honor the convention of adding test code and test resources to the Java classpath1.

Solutions

To solve this, there are several options:

  • You can manually configure your IDEA module to also depend on the test sources and all resource directories. This is only feasible when the gradle setup rarely changes, because the dependencies will be reset when the gradle project is updated.

  • You can delegate IDEA build and run tasks to Gradle, which works but is rather slow.

  • You can play around with custom class loaders or -Xbootclasspath/a:, and the like. However, this is also tricky and makes the whole setup more fragile.

  • You can play around with the raw XML that define the IDEA modules and add dependencies there (or use the idea gradle plugin’s ẁhenMerged for this). Again, this adds complexity and makes the software fragile (because newer IDEA versions may also have another XML format).

Simpler Solution

There is no perfect solution for this, but if you do not rely on gradle’s resource processing features2 you can just throwing ‘everything’ together, e.g. via

allprojects {
  apply plugin: 'idea'
  idea {
    module {
      inheritOutputDirs = false
      outputDir file("$buildDir/intellij")
      testOutputDir file("$buildDir/intellij")
    }
  }
}

This is easy to set up (should be picked up by IDEA automatically, otherwise just run gradle idea), easy to debug (if a resource or bean in the same module cannot be found, just check the contents ofbuild/intellij), and easy to use (it is separate from your gradle build output).


  1. Unfortunately, this is not configurable either. 

  2. Actually a nice feature, and still useful in all other kinds of files that are not crucial for your Spring Boot setup.