目次
- はじめに
com.github.ben-manes.versions
(Gradle Versions Plugin) とは?- Spring Boot プロジェクトにおける
io.spring.dependency-management
の役割 com.github.ben-manes.versions
の基本的な使い方mockitoAgent
のような特別な依存関係の扱い- より効率的なバージョンアップデートのワークフロー
- まとめ
はじめに
バックエンド開発でも、フロントエンドの npm-check-updates
コマンドのように、依存関係を一括で確認・アップデートできるツールはないかと常々考えていました。
Gradle を利用しているプロジェクトでも、ライブラリのバージョン管理は次第に煩雑になりがちです。
そこで見つけたのが com.github.ben-manes.versions
(Gradle Versions Plugin) でした。
この記事は、自身の備忘録として、このプラグインの基本的な使い方と、特に Spring Boot プロジェクトにおける注意点をまとめたものです。
補足:Spring Boot プロジェクトでは、io.spring.dependency-management
というプラグインが存在し、多くの依存関係のバージョンを自動で管理してくれます。
com.github.ben-manes.versions
(Gradle Versions Plugin) とは?
com.github.ben-manes.versions
は、Ben Manes 氏によって開発・メンテナンスされている Gradle のプラグインです。
Gradle プロジェクトで使用している依存関係(ライブラリ、プラグインなど)のバージョン管理を支援するさまざまな機能を提供しています。
主な機能
-
依存関係のアップデート検出
利用可能な新しいバージョン(安定版、ベータ版、アルファ版、スナップショット版など)を自動でチェックします。 -
レポートの生成
現在のバージョンと利用可能な新しいバージョンを分かりやすくまとめたレポートを生成します。 -
依存関係のフィルタリング
更新チェックの対象・除外対象をパターンで指定できます。 -
バージョン制約の管理
特定の範囲にバージョンを制限したり、特定のバージョンを禁止するルールを設定できます。
このプラグインが解決してくれる問題
Gradle Versions Plugin を導入することで、以下の課題を解決できます。
-
手動でのバージョン確認の手間から解放
ライブラリのリリース情報を個別に追跡する必要がなくなります。 -
セキュリティリスクやパフォーマンス低下の抑制
古い依存関係によるリスクを低減し、最新機能を利用しやすくなります。 -
アップデートの見落とし防止
プロジェクト全体の依存関係状況をまとめて確認できます。 -
アップデートの影響の事前評価
レポートをもとに、どのアップデートを適用するか判断材料が得られます。 -
一貫性のあるバージョン管理
プロジェクト全体で統一された依存関係管理が可能になります。 -
技術的負債の蓄積防止
定期的なアップデートにより、大規模リファクタリングのリスクを軽減できます。
Spring Boot プロジェクトにおける io.spring.dependency-management
の役割
Spring Boot プロジェクトでは、通常 io.spring.dependency-management
プラグインを適用します。
このプラグインは、Spring Boot が推奨するライブラリのバージョンを自動で管理してくれる非常に便利なものです。
例えば、build.gradle.kts
の dependencies
ブロックで以下のように記述した場合:
implementation("org.springframework.boot:spring-boot-starter-web")
バージョンを明示的に指定していなくても、io.spring.dependency-management
が Spring Boot のバージョン (3.4.5
など) に対応する適切なライブラリバージョンを選択してくれます。
これは、Spring Boot が内部的に管理している依存関係リストに基づいています。
ただし、すべての依存関係が自動管理の対象になるわけではありません。Spring Boot エコシステム外のライブラリや、特別な設定が必要な依存関係(後述の mockitoAgent
など)は、自身でバージョンを管理する必要があります。
com.github.ben-manes.versions
の基本的な使い方
1. プラグインの適用:
build.gradle.kts
の plugins
ブロックに以下を追加します。
最新バージョンは Gradle Plugin Portal で確認します。
plugins {
id("com.github.ben-manes.versions") version "0.52.0" // 執筆時点の最新
}
2. dependencyUpdates
タスクの実行:
プロジェクトのルートディレクトリで、次のコマンドを実行します。
./gradlew dependencyUpdates
3. レポートの確認:
build/dependencyUpdates/report.txt
にレポートが生成され、利用可能な新しいバージョンが確認できます。
レポートを開くと、以下のような情報が表示されます。
------------------------------------------------------------
: Project Dependency Updates (report to plain text file)
------------------------------------------------------------
The following dependencies are using the latest milestone version:
- com.github.ben-manes.versions:com.github.ben-manes.versions.gradle.plugin:0.52.0
- com.pinterest.ktlint:ktlint-cli:1.5.0
- com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.5.0
- com.pinterest.ktlint:ktlint-ruleset-standard:1.5.0
- io.mockk:mockk:1.14.0
- io.spring.dependency-management:io.spring.dependency-management.gradle.plugin:1.1.7
- org.jetbrains.kotlin:kotlin-compiler-embeddable:2.1.20
- org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.1.20
- org.jlleitschuh.gradle.ktlint:org.jlleitschuh.gradle.ktlint.gradle.plugin:12.2.0
- org.springframework.boot:org.springframework.boot.gradle.plugin:3.4.5
- org.springframework.boot:spring-boot-devtools:3.4.5
- org.springframework.boot:spring-boot-starter-test:3.4.5
- org.springframework.boot:spring-boot-starter-web:3.4.5
The following dependencies have later milestone versions:
- com.fasterxml.jackson.module:jackson-module-kotlin [2.18.3 -> 2.19.0]
https://github.com/FasterXML/jackson-module-kotlin
- io.github.detekt.sarif4k:sarif4k [0.5.0 -> 0.6.0]
https://detekt.github.io/detekt
- io.github.oshai:kotlin-logging [5.1.0 -> 7.0.7]
https://github.com/oshai/kotlin-logging
- net.bytebuddy:byte-buddy-agent [1.17.4 -> 1.17.5]
https://bytebuddy.net
- org.jetbrains.kotlin:kotlin-allopen-compiler-plugin-embeddable [2.1.20 -> 2.2.0-Beta1]
https://kotlinlang.org/
- org.jetbrains.kotlin:kotlin-build-tools-impl [2.1.20 -> 2.2.0-Beta1]
https://kotlinlang.org/
- org.jetbrains.kotlin:kotlin-reflect [2.1.20 -> 2.2.0-Beta1]
https://kotlinlang.org/
- org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable [2.1.20 -> 2.2.0-Beta1]
https://kotlinlang.org/
- org.jetbrains.kotlin:kotlin-stdlib [2.1.20 -> 2.2.0-Beta1]
https://kotlinlang.org/
- org.jetbrains.kotlin:kotlin-test-junit5 [2.1.20 -> 2.2.0-Beta1]
https://kotlinlang.org/
- org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin [2.1.20 -> 2.2.0-Beta1]
https://kotlinlang.org/
- org.jetbrains.kotlin.plugin.spring:org.jetbrains.kotlin.plugin.spring.gradle.plugin [2.1.20 -> 2.2.0-Beta1]
https://kotlinlang.org/
Gradle release-candidate updates:
- Gradle: [8.13 -> 8.14]
今回使用した build.gradle.kts
val mockitoAgent: Configuration by configurations.creating
plugins {
kotlin("jvm") version "2.1.20"
kotlin("plugin.spring") version "2.1.20"
id("org.springframework.boot") version "3.4.5"
id("io.spring.dependency-management") version "1.1.7"
id("org.jlleitschuh.gradle.ktlint") version "12.2.0"
id("com.github.ben-manes.versions") version "0.52.0"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testImplementation("io.mockk:mockk:1.14.0")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
mockitoAgent("net.bytebuddy:byte-buddy-agent:1.17.4") { isTransitive = false }
}
kotlin {
compilerOptions {
freeCompilerArgs.addAll("-Xjsr305=strict")
}
}
tasks.withType<Test> {
useJUnitPlatform()
jvmArgs("-javaagent:${mockitoAgent.singleFile.absolutePath}")
}
ktlint {
version.set("1.5.0")
verbose.set(true)
reporters {
reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE)
}
}
mockitoAgent
のような特別な依存関係の扱い
Spring Boot プロジェクトでは、mockitoAgent
のようにカスタム Configuration
を使った依存関係は、io.spring.dependency-management
の自動管理対象になりません。
val mockitoAgent: Configuration by configurations.creating
dependencies {
mockitoAgent("net.bytebuddy:byte-buddy-agent:1.17.4") { isTransitive = false }
}
この場合、net.bytebuddy:byte-buddy-agent
のバージョンが 1.17.4
と明示的に指定されています。このような依存関係については、自身で Spring Boot の依存関係管理のドキュメント Managed Dependency Coordinates を参照し、互換性のある適切なバージョンを指定する必要があります。
例えば、Spring Boot 3.4.5 の依存関係リストを確認すると、net.bytebuddy:byte-buddy
のバージョンが 1.15.11
で管理されていることが分かります。mockitoAgent
で使用する net.bytebuddy:byte-buddy-agent
も、可能な限りこのバージョンに合わせることで、互換性の問題を避けることができます。
dependencies {
mockitoAgent("net.bytebuddy:byte-buddy-agent:1.15.11") { isTransitive = false }
}
より効率的なバージョンアップデートのワークフロー
com.github.ben-manes.versions
のレポートを参考に、build.gradle.kts
のバージョンを手動で更新します。
重要ポイント:
- レポートの内容を鵜呑みにして一括更新しない
- 各依存関係のリリースノートや互換性を確認する
依存関係のアップデート時に特定のバージョンを無視する設定
com.github.ben-manes.versions
を使って依存関係の更新チェックを行うと、更新候補の中で安定版以外のバージョンが表示されることがあります。そこで、安定版のみを対象にする設定を追加しました。
また、io.spring.dependency-management
の管理対象を、更新チェックの対象から除外する設定も追加しました。
以下のコードを build.gradle.kts に追加することで、特定の条件に合致するバージョンを無視できるようになります。
// DependencyUpdatesタスクの設定。依存関係の更新チェック時に、特定の条件に合致するバージョンを無視するように設定します。
tasks.named<com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask>("dependencyUpdates") {
rejectVersionIf {
// 管理対象の依存関係リストを定義します。これらの依存関係は自動更新の対象外とします。
val managedDependencies = setOf(
"org.springframework.boot:spring-boot-starter-web",
"com.fasterxml.jackson.module:jackson-module-kotlin",
"org.jetbrains.kotlin:kotlin-reflect",
"org.springframework.boot:spring-boot-devtools",
"org.springframework.boot:spring-boot-starter-test",
"org.jetbrains.kotlin:kotlin-test-junit5",
"org.junit.platform:junit-platform-launcher"
)
// 更新候補の依存関係が管理対象リストに含まれているかをチェックします。
val isManaged = "${candidate.group}:${candidate.module}" in managedDependencies
// 更新候補のバージョンが、alpha、beta、rc、cr、mといった非安定版の識別子を含んでいるかをチェックします(大文字・小文字を区別しません)。
val isNonStable = candidate.version.contains(Regex("(?i).*[.-](alpha|beta|rc|cr|m)[.\\d-]*"))
// 管理対象の依存関係であるか、または非安定版のバージョンである場合は、更新を拒否します。
isManaged || isNonStable
}
}
再度 ./gradlew dependencyUpdates
を実行し、生成されたレポートを開くと、以下のような情報が表示されます。
------------------------------------------------------------
: Project Dependency Updates (report to plain text file)
------------------------------------------------------------
The following dependencies are using the latest milestone version:
// 省略
The following dependencies have later milestone versions:
- io.github.detekt.sarif4k:sarif4k [0.5.0 -> 0.6.0]
https://detekt.github.io/detekt
- io.github.oshai:kotlin-logging [5.1.0 -> 7.0.7]
https://github.com/oshai/kotlin-logging
- net.bytebuddy:byte-buddy-agent [1.17.4 -> 1.17.5]
https://bytebuddy.net
Failed to determine the latest version for the following dependencies (use --info for details):
- com.fasterxml.jackson.module:jackson-module-kotlin
- org.jetbrains.kotlin:kotlin-reflect
- org.jetbrains.kotlin:kotlin-test-junit5
- org.springframework.boot:spring-boot-devtools
- org.springframework.boot:spring-boot-starter-test
- org.springframework.boot:spring-boot-starter-web
Gradle release-candidate updates:
- Gradle: [8.13 -> 8.14]
The following dependencies have later milestone versions:
に表示される項目が減り、確認すべき依存関係が少なくなったことがわかります。これにより、チェック作業が楽になりました。
あとは内容を確認して、直接インポートしている依存関係のみ対応するか検討します。
まとめ
com.github.ben-manes.versions
(Gradle Versions Plugin) は、Spring Boot の依存関係管理機能 (io.spring.dependency-management
) を補完し、プロジェクトの依存関係のアップデート状況を詳細に把握し、効率的な管理を実現するためのツールであると理解しました。
Spring Boot の自動バージョン管理に頼りつつ、管理対象外の依存関係については、com.github.ben-manes.versions
のレポートや Spring Boot のドキュメントを参考に、適切なバージョン管理を心がける必要があります。
実際に com.github.ben-manes.versions
を導入してみたところ、依存関係のアップデート状況が可視化され、管理がとても楽になりました。今後は、このプラグインを定期的に活用し、計画的なアップデートを行うことで、より安定した開発ライフサイクルを送ることができると感じています。