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の機能
たいだい*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
タスクの後に自動的に実行されるようになる。
- executable jarを作るための
- run Spring Boot applications
bootRun
タスクが追加される。
- use the dependency management provided by spring-boot-dependencies
dependencies
のうち、Springが管理されるものはバージョンの記述が不要になる。
これからわかるのは、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 を使っています。
コードではこんな感じでとりこんで、こんな感じで
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の記述がスッキリしてます。(最初に出したのと見比べて見てください)
リンクされてるSpring Boot Gradle Plugin Reference Guideがしっかりしたものになってる。あとAPIドキュメントもリンクされててて開きやすくなったのも嬉しい。
Gradle 4.6では
BOMをインポートする機能がはいったのでDependency management pluginもいらない。 かも。まだ試してない。
bom をインポートする機能はfeature previewで設定を追加しないといけなかったはず https://t.co/xXSWw1nMWw
— 仄暗い水の底から (@wreulicke) 2018年3月3日
リリースノートに書いてる通り、 settings.gradle
に1行いります。
こんな感じ。
*1: たぶんこの記事でここが一番大事。
「たいだいリファレンスは先頭が重要です。」
あ、あれ?たいだい・・・?
たぶん疲れ目なので30分後に見たら違うはず https://t.co/9HeRi7Gj4B
*2:Agent指定の何かとかエンコーディング変えたりとかもあるのだけど、これらは補助的なものなので書かれてないっぽい。
SpringBoot2.0がリリースされたのでバージョンアップしてみた
待望のSpringBoot2.0がリリースされました。 ので早速バージョンアップだー。
やったことといえば、 build.gradle
のビルドスクリプトプラグインのバージョンアップだけ。
Spring Boot Gradle Plugin Reference Guide に書いてる通りですね。
- id 'org.springframework.boot' version '1.5.10.RELEASE' + id 'org.springframework.boot' version '2.0.0.RELEASE'
そしたら java
と io.spring.dependency-management
が外れるので、追加。
+ apply plugin: 'java' + apply plugin: 'io.spring.dependency-management'
対象のプロジェクトは spring-boot-starter
を使ってるだけのやつで、超シンプルなやつなのでこれだけで完了しました。
application.properties
にSpringBootのことは書いてなかったんで、そっちがどう変わったかはみてないです。とりあえず軒並みキーは変えなきゃいけないはず。
SpringFrameworkも4から5に上がるわけだけど、コンパイルエラーとかにもなんない。流石にこう言うところは安定してるなー。
変わってたとこ
なんかあったらメモがてら実装してこーかと思って。
application.properties
の空白文字の扱いが変わってた。
プロパティファイルの空白ってどう言う扱いなんだっけなと軽く探してみてみたけど、
Properties (Java Platform SE 8) くらいしか見つけられず。
そもそも Properties#load
で読むのと SpringBoot1.5で application.properties
を読むのとでも違うので、まあ、うん。
とりあえず application.properties
で値に空白文字(スペースやタブ)を使用してたら、 String#trim
されるんで消えちゃいます。
これは新しいプロパティを読むクラスで実装されてるので、 PropertyPlaceholderConfigurer. setTrimValues(false)
とかしてみても意味ないです。
ちなみにapplication.properties
ではなく、コマンドライン引数とか application.yml
とか、他の手段で設定すれば特に関係ない話です。
どうしても application.properties
でないとダメなんだーとかでもなければそちらで対応できるやつです。
もともとが正しいとも言いづらい(IDEが警告だすような記述なわけだし)ものなんで、仕様外の話かなーと。
ベタープログラマの第一部を読んだ
ベタープログラマ ―優れたプログラマになるための38の考え方とテクニック
- 作者: Pete Goodliffe,柴田芳樹
- 出版社/メーカー: オライリージャパン
- 発売日: 2017/12/15
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (4件) を見る
ベタープログラマを読もう - 日々常々で5,6,8,11,13章を読むと書きました。 実際2,4,5,6,8,11,13章を読みました。2つほど増えてますね。
雑感
部タイトル
you.write(code)
って code
を you
に書かせてる? you
は渡された code
をそのまま書くのだろうか。仮にそうだとしたら you
の型って何なんだ・・・プログラマではなさそう。もし渡した code
がそのまま書かれないとしたら write
メソッドって名前はどうなのってなっちゃうし。ところで code
は誰が生成するんだろう。 you
かしら?だとしたら code
生成と code
の write
で分かれてる? 流石に code
って変数名で型がコード的な何かじゃないってことはないと思うし・・・
2章
vimが最善です。それがすべてです。
のっけからこれ。こう言うことを書いてる本ってのがわかりやすくていいと思います。客観的な正しいっぽいことが書いているのではなく、著者が好きに書いている感じがします。
グッドリフの法則
「コードのレイアウトに関するすべての議論は、白熱すればするほど、ほぼ実りのない議論になる」
そのとおりでございます。
さて2章は「見かけのよい状態」ってのがどう言うものかを書いてます。 前に書いた 見やすいコードのために出来るたった一つのこと - 日々常々 とか、 "ふつうのJavaコーディング"を話しました - 日々常々 で話したことのいくつかとか、普段話してることと被っているものも多くありました。「そーそー、そう。これが前提、このあたりは議論の対象じゃなく、話したいのはこの先なんだー。」と言う感じ。
4章
まだやりすぎてるところ多いなーと思ったり。「結論を出さなくてもいいように、どうとでもなるように実装しておく」ってのは確かにYAGNIではあるなーと。小さいものでも不要な作り込みは不要なわけだし。
実装する前に話すのがいいってのはわかるのだけど、でも机上の空論するなら実装しちゃったもので話したほうがいいよなってのもよくみるので、この辺は意図しての使い分けかなー。
5章
自分の古いコードを読んで、そこから学ぼう、といった趣旨。
思い返してみると、自分の過去書いたコードをみる機会って案外少なかったです。長期プロジェクトは多かったけれど、プロジェクトの間にコードが変わることは少なかったかもしれない。プロジェクトが変わるタイミングでコードも変わってた感じがする。なので以前携わってたプロジェクトのコードを見たときに、ここで書いているような経験になってたかな。git以降は普段のコードを見返す機会も増えた気がする。ここ最近はプロジェクトの切れ目とかは関係なく自分のコードがころころ変わるので、昔よりも実践できてるかもしれない。
そいや昔から言ってるよなーとログ漁ってみたら
過去の自分は良い教材。
— irof::ねむい (@irof) 2010年12月17日
それっぽいのがツイッターはじめた年にあったので、もっと前から言ってそう。
あと「過去の自分は遠慮なく叩ける」とかもしょっちゅう言ってる。コードに限らず過去のブログもいい教材になります。
6章
章タイトルが謎だから読もうと思った章ですね。プロジェクトに途中参画するときにどのようにしてコードにたどり着くかって話を「航路の航行」と名付けている。なるほど。
私は途中参画もそうだけど、新規プロジェクトでも地図を描くことが多いです。地図と呼んでいる何か、ではなくて結構それっぽい地図でプロジェクトをあらわしてみる。システムの境界を海岸線であらわしたり、港や崖を描いたり、わかんないところは雲や霧で隠してみたり。傍目は遊んでるように見えたかもしれない。最近はコンテキストマップを描こうとしてる。他の人との会話に使えそうだから。
ソフトウェア考古学
たまに耳にする、具体的にはどういうものか知らない言葉が出てきた。 Wikipediaだと Software archaeology - Wikipedia とかある。まあ考古学って言うのだから、事実から文化とか状況を読み取るって感じなのだろう。メンテナンスの時によくやってるアレのことだと思う。
8章
「エラーへの言い訳」に反論するの、表面的にはできるだろうけど、反論しきろうとすると難しいなと。章タイトルの「そのエラーを無視するな!」から想像していた内容よりも具体的で強い論調だと感じました。この章は読んでみてほしい。
11章
章はじめはテスト駆動開発から入りますが、話は一応テスト全般をスコープにしてる感じです。考える機会になることがいっぱい詰め込まれてます。やはり話題としては自動テストの比重がほとんどですが。
よくある誤りは、五つのメソッドを持つクラスを見て、(略)個別のテストを五つ必要だと考えること
これを明確に「誤り」と言ってるのは初めて見たので印象深かった。理由も添えられていますが、SUTがオブジェクトとしてあまり役に立たないスメルなのかなーというのが感想。
そういえばIDEでテストクラスを生成すると、メソッドに対するテストメソッドが生成されたりしますね。あれでメソッド作ったことないですけど、ああ言う選択肢がでるのがこの辺を助長してるのかもしれない。
てことで
次は二部。そのうち。。