Gradle で Spring Boot 2 のマルチプロジェクト

Gradle を使って Spring Boot 2 のマルチプロジェクトを作る方法。


環境

Java

openjdk 10.0.2 2018-07-17

Gradle

4.10

Spring Boot

2.0.4


対象のマルチプロジェクト

|-settings.gradle

|-build.gradle
|
|-foo/
| |-build.gradle
| :
|
`-bar/
|-build.gradle
:



  • foo プロジェクトが bar プロジェクトを参照している

  • 実装内容は今回関係ないので省略


ダメパターンの設定


/build.gradle

buildscript {

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

subprojects {
apply plugin: "java"
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

repositories {
mavenCentral()
}

sourceCompatibility = 10
targetCompatibility = 10
}



/foo/build.gradle

dependencies {

compile project(":bar")
compile "org.springframework.boot:spring-boot-starter-web"
}



  • :bar への依存と、 spring-boot-starter-web への依存を宣言


コンパイル結果

> gradle :foo:compileJava

> Task :foo:compileJava FAILED
...\Foo.java:12: エラー: シンボルを見つけられません
return new Bar().bar();
^
シンボル: メソッド bar()
場所: クラス Bar
エラー1個

FAILURE: Build failed with an exception.

bar プロジェクトのクラスが解決できずにエラーになる。


説明



  • bar プロジェクトのビルド結果を確認してみる

> dir /b bar\build\

classes
tmp



  • bar プロジェクトの jar が生成されていない


    • 1.x なら、 bar\build\libs の下に bar.jar という jar ファイルが出力されており、 foo プロジェクトはその jar を参照するようになっていた気がする



  • なんか、 2.x からはデフォルトで jar プラグインの enabledfalse に設定されるようになったらしい




対処方法

java - Spring Boot multi module project with Gradle doesn't build - Stack Overflow


  • ここでは、 jar.enabledtrue を設定すればええでという方法が紹介されている

  • たしかに、これを設定すればビルドできるようになる

Gradle multi-project build dependencies of subprojects cannot be resolved · Issue #11594 · spring-projects/spring-boot


  • ただ、公式の GitHub Issue の方を見ると、そもそも依存されている側のサブプロジェクト(bar プロジェクト)の方は Spring Boot プロジェクトではないのだから、サブプロジェクトにまで org.springframework.boot プラグインを適用することが間違っていると説明されている

  • 確かにその通りだと思うので、こっちの方法で修正する


OK パターン


/build.gradle

buildscript {

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

subprojects {
apply plugin: "java"
apply plugin: "io.spring.dependency-management"

repositories {
mavenCentral()
}

dependencyManagement {
imports {
mavenBom "org.springframework.boot:spring-boot-dependencies:$springBootVersion"
}
}

sourceCompatibility = 10
targetCompatibility = 10
}



/foo/build.gradle

apply plugin: "org.springframework.boot"

dependencies {
compile project(":bar")
compile "org.springframework.boot:spring-boot-starter-web"
}



コンパイル結果

> gradle :foo:compileJava

BUILD SUCCESSFUL in 17s


説明


/build.gradle

buildscript {

ext {
springBootVersion = '2.0.4.RELEASE'
}
...
}

subprojects {
apply plugin: "java"
apply plugin: "io.spring.dependency-management"

...

dependencyManagement {
imports {
mavenBom "org.springframework.boot:spring-boot-dependencies:$springBootVersion"
}
}

...
}



  • 全てのサブプロジェクトに org.springframework.boot を設定するのをやめる

  • そして、 dependencyManagement を追加して Spring Boot の BOM を読み込む


/foo/build.gradle

apply plugin: "org.springframework.boot"

...




  • foo プロジェクトのほうにだけ org.springframework.boot を適用する