はじめに
どうも@chan_kakuです
前回こちらの記事にてSpringBoot1.5系から2.1系に上げた話をしていきました。
今回は前回のマイグレーションを受けて本格的にマイグレーションを行なった際の苦労した点などを述べていきたいと思います。
なぜ同じような記事を書いているのか
前回の記事で書いた対象のサービスは、今回のマイグレーションの対象となるサービスの前段階としてハマりそうな点などをあらかじめ知っておくために出来るだけ依存ライブラリなどが少ないものを選択して進めていました。今回の対象のサービスはSpringCloudなどに依存していたりと、前回とは違ったハマりどころが多かったため、改めて記事にしようと思いました。
行なったこと(概要)
- Gradle3系 → Gradle5系
- SpringBoot1.5系 → SpringBoot2.1系
- その他依存ライブラリのバージョンアップ
行なったこととしては初めの方は被ってるものが多い感じです。今回この記事では前回との違いを書いていきます。
SpringBoot1.5系 → SpringBoot2.1系
前回このSpringBoot自体のバージョンアップに関してはio.spring.dependency-management
の追加のみで解決していました。
しかしながら、この1.5系から2.1系で大きく変更があった箇所としてはSpring Cloudでした。
変更点1
Spring Cloudの中でもブレイキングチェンジがあったものとしては、FeignClientでした。
そもそもパッケージ構成が以下のように変更がありました
- import org.springframework.cloud.netflix.feign.FeignClient;
+ import org.springframework.cloud.openfeign.FeignClient;
元々はnetflixのFeignClientを利用していたものからOpenFeignのFeignClientに変更になりました。
これに伴い、インタフェースの変更があったりしており、その辺りの修正が必要となります。(FeignClientExceptionあたり)
外部サービスと繋がる部分であったため、ここは念入りにテストをしていきました。
変更点2
次の変更点としては、SpringBootでのデフォルトのデータソースについてです。
1.x系ではデフォルトでTomcatJDBCが利用されていました。しかしながら、2.x系からデフォルトではHikariCPが利用されるようになりました。
このHikariCPが利用されるようになったことで、エラーが出るようになりました。
SpringBoot2.x系で利用されているHikariCPのバージョンと他の依存ライブラリで利用しているHikariCPのバージョンが異なることでエラーがでていました。この辺りの話はSpringBootのissueにも上がっていましたので一度みてみてはいかがでしょうか?
対処法
今回は、エラー内容的にHikariCPのバージョン違いによるエラーであることはわかっていたので、どこかしらのSpringJDBCのバージョンが違うのだろうと推測していました。とはいえ、どのSpringJDBCのバージョンが古いのかがわからなかったため、Gradleコマンドのdependencies
を利用しました。
こちらのタスクはgradleで依存関係を追加することなく実行することができるコマンドで、以下のように実行することができます
./gradlew dependencies
こちらのコマンドを実行することで依存ツリーを確認することができます!
こちらのコマンドにより生成された依存ツリーを眺めて古いバージョンのライブラリを発見したため、そこからSpringJDBCをexcludeすることによりエラーを解消することができました。
具体的には、org.seasar.doma.boot:doma-spring-boot-starter
の最新バージョンが依存していたSpringJDBCのバージョンが古かったため、以下のようにSpringJDBCをexcludeすることで解決しました
implementation("org.seasar.doma.boot:doma-spring-boot-starter:1.1.1") {
exclude group: "org.springframework.boot", module: "spring-boot-starter-jdbc"
}
まだ解決できていないこと
上記の対処法により、jarの実行を行うことができるようにはなりました。しかしながら、gradleからbootRunを実行すると、以下のようなエラーが発生します。
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication
at jp.furyu.hoge.api.HogeApiApplication.main(HogeApiApplication.java:14)
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
このプロジェクトではbootRunオプションでclassPathの書き換えを行なっているのですが、これはこのプロジェクトの依存関係が多くなった時などに、windowsではエラーが起きてしまうらしいので書き換えを行なっています。この辺りに詳しいことが書いてありますので、ご覧になってください!
このclassPathの書き換えが原因で、どうやらbootRunできていないようなのですが、解決法がわからず、現在(2019/7)調査中です。
何か解決方法がわかり次第追記していきます!
追記(2019/8/8)
jarの名前をつける時に、今まではbuild.gradleのjarのオプションで以下のように記載していました
jar {
archiveBaseName = "hoge"
archiveFileName = "${archiveBaseName}.jar"
version = "1.0.0"
}
ローカルからjarを作るときは問題がないのですが、CIでjarを作るときは、プロジェクトのrootの名前が違うことがあり、このarchiveBase.jar
にならない現象が発生していました。
そこでCI環境でも指定したjarの名前にしたい時に今回行なった対処法は以下のようにsettings.gradleを追加しました
rootProject.name = 'hoge'
settings.gradleにrootProject.name
を追加することでCI環境でもjarの名前が変わらないようになります。
最後に
SpringBoot1.5.x系は2019年の8月でEOLなので、まだ対応されていない方は、本当に急いだ方がいいので、こちらの記事が皆さんの参考になればと思います!