かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot 1.2.x の Web アプリを 1.3.x へバージョンアップする ( その7 )( devtools を入れて java -jar で起動しても spring.thymeleaf.cache = false になる原因を調査する )

概要

Spring Boot 1.2.x の Web アプリを 1.3.x へバージョンアップする ( その6 )( JRebel と devtools をどちらも入れた時の動作を確認する ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • devtools を入れて java -jar で起動しても spring.thymeleaf.cache = false になる原因を調査する

参照したサイト・書籍

  1. 64. Spring Boot Gradle plugin
    http://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-gradle-plugin.html

  2. Spring Boot Devtools by Example
    http://stackoverflow.com/questions/37397038/spring-boot-devtools-by-example

目次

  1. devtools を入れると spring.thymeleaf.cache = false になる仕組みとは?
  2. devtools が入っていても spring.thymeleaf.cache = false にならないようにするにはどうすればよいのか?
  3. RemoteSpringApplication クラスとは?
  4. java -jar で起動した時に spring.thymeleaf.cache = false にならないようにするには結局どうする?
  5. 次回は。。。

手順

devtools を入れると spring.thymeleaf.cache = false になる仕組みとは?

spring-boot/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java の postProcessEnvironment メソッドでセットされています。ただし無条件でセットされているのではなく、引数 environment の getPropertySources() メソッドが返す PropertySource リストの中に "remoteUrl" という名称のものがなければセットしているようです。

environment.getPropertySources() が返す PropertySource リストを Debug モードで実行して確認したところ、以下の画像の結果でした。確かに "remoteUrl" のものはありませんでした。

f:id:ksby:20160529223533p:plain

devtools が入っていても spring.thymeleaf.cache = false にならないようにするにはどうすればよいのか?

environment.getPropertySources() が返す PropertySource リストの中に "remoteUrl" という名称のものがあればセットされるので、どうやればセットされるのかを調査します。

Spring Boot の GitHub の画面右上の Search フィールドに "remoteUrl" を入力して検索してみます。

f:id:ksby:20160529224851p:plain

ヒットしたのは以下の5つのファイルでした。

  • spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/RemoteClientConfiguration.java
  • spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractor.java
  • spring-boot-devtools/src/test/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractorTests.java
  • spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java
  • spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/RemoteClientConfigurationTests.java

ざっと見てみると spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractor.java の onApplicationEvent メソッドで "remoteUrl" PropertySource をセットしているようです。

RemoteUrlPropertyExtractor#onApplicationEvent メソッドでは、nonOptionArgs プロパティにセットされている URL をセットした "remoteUrl" PropertySource を生成して environment にセットしています。

RemoteUrlPropertyExtractor クラスがどこで呼び出されているか調べてみます。GitHub の画面右上の Search フィールドに "RemoteUrlPropertyExtractor" を入力して検索します。

f:id:ksby:20160529230927p:plain

ヒットしたのは以下の3つのファイルでした。

  • spring-boot-devtools/src/test/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractorTests.java
  • spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractor.java
  • spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteSpringApplication.java

spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteSpringApplication.java の getListeners メソッドで listeners.add(new RemoteUrlPropertyExtractor()); と呼んでいますね。

RemoteSpringApplication クラスを見た感じでは RemoteSpringApplication#main メソッドが呼び出されればRemoteSpringApplication#run メソッドが呼び出されて、その中で getListeners メソッドが呼び出されます。

結局、devtools が入っていても spring.thymeleaf.cache = false にならないようにするためには以下のように ksbysample.webapp.lending.Application#main メソッドを呼び出さずに RemoteSpringApplication#main メソッドを呼び出して起動する、という方法のようです。

  • DevToolsPropertyDefaultsPostProcessor#postProcessEnvironment で environment.getPropertySources() が返す PropertySource リストの中に "remoteUrl" という名称のものがあれば spring.thymeleaf.cache = false にはならない。
  • nonOptionArgs プロパティに URL がセットされた状態で RemoteUrlPropertyExtractor#onApplicationEvent が呼び出されれば environment.getPropertySources() が返す PropertySource リストの中に "remoteUrl" という名称のものが作成される。
  • RemoteSpringApplication#main が呼び出されれば、そこから呼び出される RemoteSpringApplication#run の中で RemoteUrlPropertyExtractor クラスのインスタンスが生成されて Listener としてセットされ、RemoteUrlPropertyExtractor#onApplicationEvent が呼び出されるようになる。

RemoteSpringApplication クラスとは?

RemoteSpringApplication クラスがそもそも何のためのクラスなのかが分からなかったので調査します。

Spring Boot Reference Guide の以下の章に RemoteSpringApplication クラスの記述がありました。読んだ感じでは URL を指定して Remote の Spring Application に接続するためのクラスのようです。

でも別に Remote の Spring Application に接続したい訳ではないので、RemoteSpringApplication#main を呼び出すのは何か求めているものと違う気がします。

java -jar で起動した時に spring.thymeleaf.cache = false にならないようにするには結局どうする?

java -jar で起動すると devtools が無効になるようには全く見えません。20. Developer tools をもう1度見てみると "Developer tools are automatically disabled when running a fully packaged application. " と書かれているのですが、"when running a fully packaged application." というのが単に jar ファイル作るのとどう違うのかも全然分かりません。

ちょっと今回は降参です。。。

何か他に方法がないかいろいろ探してみたところ、64. Spring Boot Gradle plugin に jar ファイルを作成する時に devtools.jar を入れないようにするための excludeDevtools オプションなるものがあると書かれているのを見つけました。これを設定して jar ファイルには devtools が入らないようにしてみたいと思います。

次回は。。。

excludeDevtools オプションを指定して jar ファイルには devtools を入れないようにした場合の動作確認をします。

ソースコード

履歴

2016/05/31
初版発行。