日々常々

ふつうのプログラマがあたりまえにしたいこと。

Spring Boot Gradle Pluginの話(Spring Boot 1.5.x & Gradle 4.5)

Spring Boot 1.5.x とGradle 4.5 の話です。Spring Boot 2.0とGradle4.6が出たので、埋葬がてら書いておきます。 どんな感じで要らない話になったのかは最後に書いてます。

Spring Boot Gradle Pluginの機能

67. Spring Boot Gradle plugin

たいだい*1 だいたいリファレンスは先頭が重要です。なぜか読み飛ばされがち。コードがあったらそっち読んじゃうのはわかるけど。

The Spring Boot Gradle Plugin provides Spring Boot support in Gradle, allowing you to package executable jar or war archives, run Spring Boot applications and use the dependency management provided by spring-boot-dependencies.

  • allowing you to package executable jar or war archives
    • executable jarを作るための bootRepackage タスクが追加され、 jar タスクの後に自動的に実行されるようになる。
  • run Spring Boot applications
    • bootRun タスクが追加される。
  • use the dependency management provided by spring-boot-dependencies
    • dependencies のうち、Springが管理されるものはバージョンの記述が不要になる。

つまり、プラグインの機能は主に3つ*2ということ。

これからわかるのは、Spring Boot Gradle PluginはSpringBootアプリケーションプロジェクト(Mainクラスが入ってるやつ)には適切だけれど、SpringBootアプリケーションから使用されるモジュールにはdependency management以外は不要なので微妙ってことです。2/3を使ってないわけですからね。

単一モジュールで作っているなら問題にならないだろうけど、共通で使うモジュールとか作る際にうっかり使っちゃうと困ることになる。使わないもの( bootRun タスクがそれ)はまだいいのだけど、勝手に動作する( bootRepackage タスクがそれ)のが問題なのです。

起こりうる問題

たとえばこういう問題が起こります。

  • Main クラスがないのでビルドエラーになる。
  • (仮に最初のを回避したとして)依存ライブラリがjarの中に入る。

他にもあるかもしれないけど、知らない。

対処

  • (だめ) Mainクラスを作る
  • (だめ)bootRepackage.layout = 'MODULE'
  • bootRepackage をしない
  • Dependency management plugin だけ使う

それぞれ書いていきます。

Mainクラスを作る

Mainクラスがないからエラーとか言われるからってMainクラスを作るやつ。要らないもの作っちゃだめですね。

レイアウトをMODULEにする

Mainクラスがなくてもビルドできます。モジュールを作ってるんだからそれっぽく見えるかもしれませんが、jarの中に依存ライブラリがぶっこまれます。そんなjarいらない。無駄にでかくなるし。

bootRepackageしない

そもそもrepackageする必要がないので止めちゃいましょう。

bootRepackage {
    enabled = false
}

シンプルだし、プロジェクトによって使うGradle Pluginを変えなくていいというのはメリットかもしれません。技術スタックは少ない方がいいので。

でも使用しないタスクが入るところは微妙かも。

Dependecy management pluginを使う

Sprign Boot Gradle Pluginは中で Dependency management plugin を使っています。

GitHub - spring-gradle-plugins/dependency-management-plugin: A Gradle plugin that provides Maven-like dependency management functionality

コードではこんな感じでとりこんで、こんな感じspring-boot-starter-parent をインポートしてます。これをDependency management Plugin を使う形で build.gradle に書くとこうなります。

plugins {
    id "io.spring.dependency-management" version "1.0.4.RELEASE"
}

...

dependencyManagement {
    imports {
        mavenBom 'org.springframework.boot:spring-boot-starter-parent:1.5.10.RELEASE'
    }
}

これで余計なタスクも入らない。Spring Bootアプリケーションを作ってるわけではないのだから、たぶんこれでいいはず。

モジュールの独立性とか言ったら(bomとはいえ)SpringBootに依存するのはどうなのとかあるでしょうけど、バージョンの整合性を取るのは面倒だし、自分たちしか使わないモジュールならこれでよかろーです。

Spring Boot 2.0では

マイグレーションガイドに書かれている通り、Spring Boot Gradle Pluginからdependency managementは除外されています。

Spring Boot 2.0 Migration Guide · spring-projects/spring-boot Wiki · GitHub

あと変わったことといえば、Spring BootのリファレンスのSpring Boot Gradle Pluginの記述がスッキリしてます。(最初に出したのと見比べて見てください)

69. Spring Boot Gradle Plugin

リンクされてるSpring Boot Gradle Plugin Reference Guideがしっかりしたものになってる。あとAPIドキュメントもリンクされててて開きやすくなったのも嬉しい。

Gradle 4.6では

Gradle 4.6 Release Notes

BOMをインポートする機能がはいったのでDependency management pluginもいらない。 かも。まだ試してない。

リリースノートに書いてる通り、 settings.gradle に1行いります。

github.com

こんな感じ。

*1:

*2:Agent指定の何かとかエンコーディング変えたりとかもあるのだけど、これらは補助的なものなので書かれてないっぽい。