Gradle で Maven BOM を作る

概要

Gradle で複数のプロジェクトでバージョンを共通なものにしたい場合などのために BOM を作成する。

前提

ここでは下記バージョンをもとにしたドキュメントやソースを参照している

BOM とは

"bill of materials" 、つまり部品表の略。(あるいは "build of materials" と記載されている例もある) アーティファクトを列挙し、その BOM を利用する際に依存するバージョンを統一することができる。

maven.apache.org

BOM の例

Spring Boot Dependencies

Spring Boot の BOM, 基本的には Spring Boot で開発する場合はこれが使われており、 Spring Boot 内で使われているものと同じバーションのものをアプリケーション側でも利用することが多いと思う。

Spring Boot の依存関係は別途 HTML ドキュメントとして出力されており、下記のようにドキュメントのページで確認できる。

軽く触ったりする場合などは明示的に使っているパターンは少なくて、通常は下記のような Gradle Plugin が自動的に Spring Boot Dependencies を import してくれている。

Spring Framework BOM/Spring Security BOM

Spring Framework の BOM。基本的には リリースされるモジュールのバージョンを一括で登録してある BOM となっているようにみえる。

Spring Boot Dependencies にも利用されている。

spring-boot/pom.xml at v2.2.0.M4 · spring-projects/spring-boot · GitHub

JUnit BOM

JUnit の BOM

AWS Java SDK BOM

AWS Java SDK の BOM

Gradle で BOM を作成する

Magen の pom.xml ではそのまま DepenendencyManagement セクションにアーティファクト情報を記載すれば良い。

gradle の場合は方法は確認した限りでは2つ。

  • java-platform-plugin を利用する
  • spring team の DependencyManagment plugin を利用する

java-platform-plugin を利用する

docs.gradle.org

dependencies 以下に constrains として追加する。おそらく基本的には api を用いると思う(理由は未調査)

dependencies {
    constrains {
        api 'org.springframework:spring-core:4.0.3.RELEASE'
    }
}

scope import の場合は dependendy として追加する。 java-platform plugin はデフォルトでは dependencies は許可されてないので別途 許可する設定を追加する。

javaPlatform {
    allowDependencies()
}

dependencies {
    api platform('io.spring.platform:platform-bom:1.0.1.RELEASE')
}

publish する場合は maven-publish plugin を利用して以下のように記述する。

publishing {
    publications {
        maven(MavenPublication) {
            from components.javaPlatform
        }
    }
}

spring team の DependencyManagment plugin を利用する

Gradle の場合は 依存性の記載には spring チームが出している Dependency Management Plugin を利用する。 これを利用することによって MavenDependencyManagement セクションで行うような記載ができるようになる。

plugins.gradle.org

docs.spring.io

dependencyManagement {
    dependencies {
        dependency 'org.springframework:spring-core:4.0.3.RELEASE'
    }
}

scope import の場合

dependencyManagement {
    imports {
        mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE'
    }
}

dependencies には下記のようにバージョン情報を抜いて記載できる。この場合は dependencyManagement に記載のある 4.0.3.RELEASE が利用される。

dependencies {
  implementation 'org.springframework:spring-core'
}

ここまではまあ通常の用途で、その記載対象となるプロジェクト下でのバージョン情報や、 multiproject などで sub project でのバージョン情報などを省略できる。

他の独立したプロジェクト(別リポジトリ等)で利用したい場合は その dependencyManagement 情報を publish する必要がある。このとき必要なのが maven-publich プラグインである。(maven リポジトリの場合) これを使うことで gradle のプラグインで記載された dependencyManagement を pom.xml で出力し、 maven リポジトリを通じてその他のプロジェクトで利用できる形にできる。

Maven Publish Plugin

publishing {
    publications {
        maven(MavenPublication) {
        }
    }
}

例: Gradle scripts to generate a BOM and then consume that BOM · GitHub

また pom.xml 側で記載されているような properties を記載したい場合には以下のように書く。

publishing {
    publications {
        maven(MavenPublication) {
            pom {
                properties['spring.boot.version'] = '2.2.0.M4'
            }
        }
    }
}

ローカルで使って見る場合には publishToMavenLocal タスクを使って local repo に入れたうえで 利用側で mavenLocal() の記載があれば maven repository にデプロイしなくても確認できると思う。

Gradle で BOM を利用する

使い方はおそらく2つ。

  • Gradle Dependency Management Plugin の imports に記載する。
  • Gradle 5.0 以上の場合は implementation platform() する

前者の場合は dependencyMananement の部分に imports で記載すると利用できる。

dependencyManagement {
     imports {
          mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE'
     }
}

dependencies {
     compile 'org.springframework.integration:spring-integration-core'
}

Dependency Management Plugin

後者の場合は Gradle 5.0 から Gradle 側で利用方法が提供されているためその書き方もできる。

dependencies {
    // import a BOM
    implementation platform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE')

    // define dependencies without versions
    implementation 'com.google.code.gson:gson'
    implementation 'dom4j:dom4j'
}

gradle.org

注意点としては lombokannotationProcessor の利用が必要な場合は annotationProcessorにも BOM の記載が必要になる。

stackoverflow.com

以上