先延ばししがちな技術負債
ソフトウェア開発において、オープンソースライブラリを活用することは、開発効率を高めます。しかし、その一方で依存関係の管理は複雑で、古くなったライブラリはセキュリティリスクともなります。これらの問題を解決するために、ライブラリの継続的な最新化は欠かせません。
定期的にライブラリを最新バージョンに更新することが不可欠なのは分かっているが、手作業での更新は非常に手間がかかり、エラーが発生するリスクも高いので、先延ばしにしてしまっている人も多のではないでしょうか?
直ちにリスクが顕在化するというわけでもないのですが、技術負債を夏休みの宿題の如くどんどん貯め込んでいると返す頃になって、大きなコストを支払うことになります。しかも、いまどきのオープンソースライブラリの無料サポート期間は短く、半年や1年のスパンで最新版の提供に切り替わっていきますので、できるだけ最新にライブラリを保っていかないとあっという間に取り残されてしまいます。
とはいえ、先延ばし、しちゃいますよね。
OpenRewrite
OpenRewriteは、(主に)Javaコードを自動的に修正するためのオープンソースツールです。Spring Bootの最新化のような大規模なマイグレーションにおけるリファクタリング作業を、わずか数行のコードで自動化することができます。
これを使えば、もう先延ばししなくても済みます。
試してみる
Spring Bootは、Webアプリケーション開発でよく使われるフレームワークですが、マイグレーションにはSpring本体だけでなく、関連ライブラリも更新する必要があります。手動で行うと非常に時間を要する作業となります。特にバージョンをまたがる程のマイグレーションには、マイグレーション自体を諦めたくなるほど膨大な作業の発生を覚悟しなければならないかも知れません。
そんなSpring BootのマイグレーションでOpenRewiteを体感してみましょう。少し古いSpring Bootのアプリケーションを用意します。少し前に作ったSpring Bootを使ったアプリケーションなら3.1や3.2なのではないでしょうか?
準備
OpenRewiteではマイグレーション手順は、レシピと呼ばれており、たくさんのレシピ(マイグレーション手順)が用意されています。
今回は Spring Boot 3.3 へのマイグレーションを試してみます。
Recipe > catalog > Java > Spring > Spring Boot 3.x > Migrate to Spring Boot 3.3
Usageに使い方が記載されていますが、実に簡単です。Gradleを使っている場合は、build.gradleに下記を追加するだけです。
plugins {
id("org.openrewrite.rewrite") version("6.28.4")
}
rewrite {
activeRecipe("org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_3")
setExportDatatables(true)
}
repositories {
mavenCentral()
}
dependencies {
rewrite("org.openrewrite.recipe:rewrite-spring:5.24.1")
}
マイグレーション実行
./gradlew rewriteRun
またはIDEのプラグインなどでGradleタスクからレシピを実行します。OpenRewriteがコードを解析し、自動的に修正を行ってくれます。
Validating active recipes
Scanning sources in project :spring-boot-sample
Using active styles []
All sources parsed, running active recipes: org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_2
Changes have been made to spring-boot-sample/src/main/java/com/sample/Application.java by:
org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_1
org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0
org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakarta
org.openrewrite.java.migrate.jakarta.JavaxAnnotationMigrationToJakartaAnnotation
org.openrewrite.java.ChangePackage: {oldPackageName=javax.annotation, newPackageName=jakarta.annotation, recursive=true}
ローカルのソースの変更差分を確認すれば、実際にソースに修正が行われたことが確認できると思います。
あとは修正されたソースを確認して、テストを実行してコミットするだけです。
修正箇所を洗い出して手動で修正していた頃にはもう戻れないと思います。
ちなみに、ビルド成果物のフォルダには日付フォルダが作成され、マイグレーション結果のファイルが作成されます。(使い道としてはエラーが出た時に確認するくらいかなと思いますが…)
build\reports\rewrite\datatables\yyyy-MM-dd_hh-mm-ss-SSS
org.openrewrite.maven.table.DependenciesInUse.csv
org.openrewrite.table.RecipeRunStats.csv
org.openrewrite.table.SourcesFileErrors.csv
org.openrewrite.table.SourcesFileResults.csv
org.openrewrite.table.SourcesFiles.csv
テストコード大事
今回 OpenRewite を使ってみて、テストコードの存在がとても大事なことを改めて感じました。
確かに OpenRewite はマイグレーションに必要なコード修正を自動で行ってくれる便利なツールですが、一方でマイグレーションされたソースコードが、アプリケーションして正しく動作するか、についてはもちろん保証してくれません。アプリケーションして正しく動作するか、を保証するのはテストです。ユニットテストやE2Eテストがしっかり整っていればこそ、安心してアプリケーションしての動作を担保してコミットすることができます。
私の在籍するチームは、全員がテストコードをせっせと作り、メンテナンスする風土の中にあります。だからこそ、OpenRewite での修正結果を確認後、アプリケーションしての動作をテスト実行で担保して安心してコミットすることができます。OpenRewiteで楽した分、今後もテストコードの拡充に励んで、ライブラリをできるだけ最新に保っていこうと思います。
まとめ
とうことで、OpenRewiteを使うのは超簡単 2ステップです。
- build.gradle(MavenならPOM.xml)に設定を数行追加
-
./gradlew rewriteRun
またはIDEのプラグインなどでGradleタスクからレシピを実行
今回はSpring Bootで試しましたが、レシピには、Java8 からのマイグレーションや Log4j、Quarkus のマイグレーション手順など様々用意されています。時折チェックすると新たなレシピが追加されているかも知れません。
いずれも非常に簡単に試せるので、ぜひ実際に動かしてみることをおすすめします。