Spring Boot 1.2/1.3でhot swapping的なこと
唐突にJavaの話。Spring Bootで変更を動的に反映する場合(いわゆるhot swappingとかhot deploy)はSpring Loadedを使えって出てくるのだけど、なんか動いたり動かなかったりしてなんでなんだろうと小一時間調べたメモ。Spring Boot + Maven + IntelliJ IDEA 15 on Mac 前提。
Spring Boot 1.2 with Spring Loaded
現行バージョンのSpring Boot 1.2では、Spring Loaded使えということになっている。
公式マニュアル通りにpom.xmlでsrping-boot-maven-plugin
にSpring Loadedへの依存を書くだけで CLIからmvnを叩いた場合 は普通に使える。
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.4.RELEASE</version> </dependency> </dependencies> </plugin>
IntelliJ IDEAでの罠
ただし、IntelliJから使う場合はいくつかの罠がある。
IntelliJではビルド実行/デバッグ実行中はauto compileが無効
- IntelliJの設定で "Make project automatically" を有効にしても、ビルドの実行/デバッグ中はファイルを変更しても自動コンパイルされない
- これはIntelliJの仕様 http://stackoverflow.com/a/12744437
- Save and Make 的なマクロを作って Shift + Command + S に割当てるとかするしかない
IntelliJのSpring Bootビルド設定はpomを読んでくれない
- pomにSpring Loadedの依存を書いても、IntelliJ組み込みのSpring Bootビルド設定から実行するとjavaagentの設定が有効にならない
- VMオプションに
-javaagent:<pathto>/springloaded.jar -noverify
を書けば動く
- VMオプションに
- Spring BootビルドではなくMavenビルドから
spring-boot:run
で実行すればOK
つまり、Save and Makeマクロ書いてMavenビルドすればOK。Spring Loadedがちゃんと動くかはさておき。
Spring Boot 1.3 with devtools
次期バージョンのSpring Boot 1.3(現在RC1)からは、新規追加されるspring-boot-devtools
を使うことでクラスパス上のファイルが更新された場合に自動的にアプリを再起動できるようになる。
再起動っていうと遅そうだけど、そこはトリックを使ってSpring Loadedほどではないが実用レベルに高速化している。仕組みとしては、まずクラスローダを2つ用意して、サードパーティライブラリ用クラスローダだと開発中のローカル用クラスローダに分ける。そして再起動時は後者のみを破棄して新規に作り直すことで、変化しないサードパーティライブラリの大量のクラスを読みなおすことを抑止して高速化しているとのこと。つまり巨大モノリシックなアプリ以外ならそこそこ速いのではないか。
設定は例によってpomを書くだけ。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies>
devtoolsにはこのauto restartの他にも、ブラウザ拡張のLive reloadに対応、テンプレートのキャッシュを開発時は自動で無効化など、デフォルトで開発が楽になる仕組みが入っていて便利。
IntelliJのSpring Bootビルド設定でもdevtoolsは有効だった。ただしIntelliJでは相変わらず自動コンパイルはできない(仕様)ので、前述のマクロは必要。
JavaのHot swappingって昔から信用できない印象があるので(なぜか挙動が微妙なので結局アプリ再起動しよう、みたいな)、ちょっともたつくけどdevtoolsの再起動方式のが好みかな。
追記
期待し過ぎないように@makingさんのコメントを追記しておきます。
@teppeis 1.3のもうまくリロードできたらラッキーレベルですwリロード後にコンポーネントが見つからないとかありますね。あとは個人用途ならmyJrebelとか https://t.co/bDSwp3egF5 こっちの方が安定してます。初回起動遅くて使わなくなりましたが
— Toshiaki Maki (@making) 2015, 11月 3