🐘

Gradle DependencyManager の基本を Spring Boot で学ぶ

に公開

はじめに

前回からの4回目です。

これまでの学習は以下です。

  1. Gradle Projects の基本を Spring Boot で学ぶ
  2. Gradle Tasks の基本を Spring Boot で学ぶ
  3. Gradle Plugins の基本を Spring Boot で学ぶ

本稿は DependencyManager が対象です。

依存関係のタイプなどの概念をまとめています。

本稿の内容は(自分で述べるのもなんですが)薄いのですが、「第一回のはじめに」で述べたように、Gradel を4つに分けて理解することが趣旨だったので、ご了承下さい。

[注]

筆者は Java に精通しているわけでも SpringBoot に精通しているわけでもありません。

現在進行形で学習しており、その内容の理解のためにブログでまとめています。
なお、IDEはVSCodeです。

DependencyManager とは

Gradle プロジェクトで使用する外部ライブラリやモジュールの依存関係を管理します。

おさえるべき3つの概念が以下です。

DependencyManager でおさえるべき3つの概念

  1. 依存関係のタイプ
  2. 依存関係の構成のタイプ
  3. プロジェクトにおける依存管理の方法

それぞれ順に見ていきます。

1 依存関係のタイプ

どこから依存関係のあるリソース取得するかでタイプが分かれます。

タイプ 場所 宣言方法 使用例 備考
モジュール依存関係 外部リポジトリ(e.g. mavenCentral, maven, google, URL, etc) group:name:version形式 implementation 'org.springframework:spring-web:5.0.2.RELEASE' リポジトリの設定が必要
インターネット接続が必要
プロジェクト依存関係 同じビルド内の他プロジェクト project(':name')形式 implementation project(':shared') プロジェクト構造の適切な設計が必要
settings.gradleでの設定が必要
ファイル依存関係 ローカルファイルシステム上のファイル files(), fileTree()メソッド implementation files('libs/custom.jar') バージョン管理が手動
推移的依存関係の解決なし

2 依存関係のスコープ

Understanding dependency configurations を確認すると良さそうです。

どのタイミングで依存関係があるかを宣言します。

カスタマイズして設定することも可能です。

dependencies {
    implementation("com.google.guava:guava:30.1.1-jre")  // Implementation dependency
    compileOnly("org.projectlombok:lombok:1.18.20")      // Compile-only dependency
    runtimeOnly("mysql:mysql-connector-java:8.0.23")     // Runtime-only dependency
}

3 プロジェクトにおける依存管理の方法

Platforms と Version Catalog の2つのアプローチがあります。

両者は排他的な関係ではなく、両方を組み合わせて使用することも可能のようです。

Dependency Management Basics には、 Version Catalog のみ紹介されていることから推したいのは、こちらだと思いました。

Version Catalog を使ったマルチプロジェクト

前回 に導入した設定を再掲します。

2 の依存関係の構成スコープを確認すると、buildSrc/build.gradle における toml ファイルの読み込みは、 implementation から compileOnly に変更できそうです。(ランタイム時にファイルは必要ではないため)

// gradle/libs.versions.toml
[versions]
spring-boot = "3.4.2"
spring-dependency = "1.1.7"
checkstyle = "10.21.2"

[libraries]
spring-boot-starter-web = { group = "org.springframework.boot", name = "spring-boot-starter-web" }
spring-boot-starter-test = { group = "org.springframework.boot", name = "spring-boot-starter-test" }
junit-platform-launcher = { group = "org.junit.platform", name = "junit-platform-launcher" }
spring-boot-gradle-plugin = { group = "org.springframework.boot", name = "spring-boot-gradle-plugin", version.ref = "spring-boot" }

[plugins]
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
spring-dependency = { id = "io.spring.dependency-management", version.ref = "spring-dependency" }
// buildSrc/settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        libs {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}
// buildSrc/build.gradle
plugins {
    id 'groovy-gradle-plugin'
}

repositories {
    mavenCentral()
}

dependencies {
    compileOnly files(libs.class.superclass.protectionDomain.codeSource.location)
    implementation libs.spring.boot.gradle.plugin
}
plugins {
    id 'java'
    id 'checkstyle'
    id 'org.springframework.boot'
    id 'io.spring.dependency-management'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

repositories {
    mavenCentral()
}

checkstyle {
    toolVersion = libs.versions.checkstyle.get()
}

dependencies {
    implementation libs.spring.boot.starter.web
    testImplementation libs.spring.boot.starter.test
    testRuntimeOnly libs.junit.platform.launcher
}

tasks.named('test') {
    useJUnitPlatform()
}

// {hoge,fuga}/build.gradle
plugins {
    id 'demo-conventions'
}

上記の設定が以下のように、各ビルド時に必要な依存関係が解決されて、サブプロジェクトまで流れていっているのが分かります。

さいごに

最上位概念の Projects から始め、その次に Plugins の実体となる Tasks を理解し、配布可能な共有物となる Task である Plugins を理解して、依存性管理の Dependency Management を理解して Gradle の概要を掴むのが本ブログの趣旨でした。

当初とっつきにくい印象だった Gradle ですが、ここまでの学習である程度見通しが立ったと思いました。

ここまでの利用で最も理解が重要だと感じたのが、buildSrc の独立性、優先性です。コケるたびに buildSrc の特殊性に引っかかった気がします。

公式ドキュメントはかなりまとまってはいてありがたいことです。
ここまでのブログの中身は、ほぼ公式ドキュメントの焼き直しに過ぎません。

(とはいえ、痒いところは書いてなかったりする感はありました。そこらへんはフォーラムなどを確認すると良さそうです)

今後は実際に使いながら Gradle の理解を深めていきたいと思います。

参考リンク

Discussion