LoginSignup
29
26

More than 3 years have passed since last update.

Dependency Management Plugin 使い方メモ

Posted at

Dependency Management Plugin とは

Spring Project で開発されている(と表現していい?) Gradle のプラグイン。
Maven の BOM と同等の仕組みを Gradle でも使えるようにするためのもの。

BOM の説明は Gradle で BOM を使いたいときには Spring チームの出している Dependency management plugin を使うのがよさそう - なにか作る などを参照。

もともと Spring Boot 1.x の頃は Spring Boot プラグインの一部だったが、 Spring Boot が 2.x になったときに独立したプラグインとして分離された。 +
なので、 Spring Boot とは関係なく利用できる(でも、実際一番お世話になるのは Spring Boot を使うときだと思う)。

環境

Gradle

5.4.1

Dependency Management Plugin

1.0.8.RELEASE

Hello World

build.gradle
plugins {
    id "java"
    id "io.spring.dependency-management" version "1.0.8.RELEASE"
}

repositories {
    mavenCentral()
}

dependencyManagement {
    dependencies {
        dependency "org.apache.commons:commons-lang3:3.9"
    }
}

dependencies {
    implementation "org.apache.commons:commons-lang3"
}

sourceCompatibility = 11
targetCompatibility = 11

compileJava.options.encoding = "UTF-8"
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
\--- org.apache.commons:commons-lang3 -> 3.9

説明

build.gradle
dependencyManagement {
    dependencies {
        dependency "org.apache.commons:commons-lang3:3.9"
    }
}
  • dependencyManagementdependencies で、依存ライブラリをバージョンまで宣言する
build.gradle
dependencies {
    implementation "org.apache.commons:commons-lang3"
}
  • すると、プロジェクトの通常の依存関係の定義からバージョンの記述を省略できるようになる
  • この場合は、 dependencyManagement で宣言したバージョンがデフォルトで使用されるようになる

同じグループの複数のアーティファクトのバージョンを一括で宣言する

build.gradle
...

dependencyManagement {
    dependencies {
        dependencySet(group: "org.apache.poi", version: "4.1.0") {
            entry "poi"
            entry "poi-ooxml"
        }
    }
}

dependencies {
    implementation "org.apache.poi:poi"
    implementation "org.apache.poi:poi-ooxml"
}

...
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.poi:poi -> 4.1.0
|    +--- commons-codec:commons-codec:1.12
|    +--- org.apache.commons:commons-collections4:4.3
|    \--- org.apache.commons:commons-math3:3.6.1
\--- org.apache.poi:poi-ooxml -> 4.1.0
     +--- org.apache.poi:poi:4.1.0 (*)
     +--- org.apache.poi:poi-ooxml-schemas:4.1.0
     |    \--- org.apache.xmlbeans:xmlbeans:3.1.0
     +--- org.apache.commons:commons-compress:1.18
     \--- com.github.virtuald:curvesapi:1.06

説明

build.gradle
dependencyManagement {
    dependencies {
        dependencySet(group: "org.apache.poi", version: "4.1.0") {
            entry "poi"
            entry "poi-ooxml"
        }
    }
}
  • dependencySet を使うと、同じグループの複数のアーティファクトのバージョンを一括で指定できる
    • グループは org.apache.poi で、アーティファクトは poipoi-ooxml
    • バージョンに 4.1.0 を指定している

推移的な依存関係から特定のライブラリを除外する

build.gradle
...

dependencyManagement {
    dependencies {
        dependency("org.apache.poi:poi:4.1.0") {
            exclude "commons-codec:commons-codec"
        }
    }
}

dependencies {
    implementation "org.apache.poi:poi"
}

...
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
\--- org.apache.poi:poi -> 4.1.0
     +--- org.apache.commons:commons-collections4:4.3
     \--- org.apache.commons:commons-math3:3.6.1
  • 前節の依存関係のグラフと比較すると、 commons-codec が無くなっているのが分かる

説明

build.gradle
dependencyManagement {
    dependencies {
        dependency("org.apache.poi:poi:4.1.0") {
            exclude "commons-codec:commons-codec"
        }
    }
}
  • exclude() を使うことで、推移的な依存関係の中にある特定のライブラリを除外できる

dependencySet で指定する場合

build.gradle
...

dependencyManagement {
    dependencies {
        dependencySet(group: "org.apache.poi", version: "4.1.0") {
            entry("poi") {
                exclude "commons-codec:commons-codec"
            }
            entry "poi-ooxml"
        }
    }
}

dependencies {
    implementation "org.apache.poi:poi"
    implementation "org.apache.poi:poi-ooxml"
}

...
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.poi:poi -> 4.1.0
|    +--- org.apache.commons:commons-collections4:4.3
|    \--- org.apache.commons:commons-math3:3.6.1
\--- org.apache.poi:poi-ooxml -> 4.1.0
     +--- org.apache.poi:poi:4.1.0 (*)
     +--- org.apache.poi:poi-ooxml-schemas:4.1.0
     |    \--- org.apache.xmlbeans:xmlbeans:3.1.0
     +--- org.apache.commons:commons-compress:1.18
     \--- com.github.virtuald:curvesapi:1.06

BOM を読み込む

build.gradle
...

dependencyManagement {
    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }
    }
}

dependencies {
    implementation "org.apache.commons:commons-lang3"
}

...
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
\--- org.apache.commons:commons-lang3 -> 3.8.1

説明

build.gradle
dependencyManagement {
    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }
    }
}
  • importsmavenBom で、 Maven の BOM を読み込むことができる
  • ここでは Spring Boot 2.1.6.RELEASE の BOM を読み込んでいる
  • 2.1.6.RELEASE の BOM で指定されている commons-lang3 のバージョンは 3.8.1 なので、解決されたバージョンも 3.8.1 になっている
  • 複数の BOM をインポートすることもできる
    • その場合、同じアーティファクトのバージョンは最後にインポートした BOM の宣言が使用される

BOM で宣言されたバージョンを上書きする

バージョンプロパティを上書きする

build.gradle
...
dependencyManagement {
    dependencies {
        imports {
            mavenBom("org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE") {
                bomProperty "commons-lang3.version", "3.9"
            }
        }
    }
}

dependencies {
    implementation "org.apache.commons:commons-lang3"
}
...
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
\--- org.apache.commons:commons-lang3 -> 3.9

説明

build.gradle
            mavenBom("org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE") {
                bomProperty "commons-lang3.version", "3.9"
            }
  • Maven BOM 上でプロパティを使ってバージョンが宣言されている場合、そのプロパティの値を上書きすることでバージョンを変更できる
    • Spring Boot の BOM では、 commons-lang3 のバージョンは commons-lang3.version というプロパティで宣言されている
  • ただし、この方法はMaven プラグインで pom.xml を出力しない場合にのみ使用すべき
    • なぜなら、この方法だと出力される pom.xml にはバージョンを上書きしているという情報が反映されないため

bomProperties(Map) を使う書き方もある。

bomProperties(Map)で指定する例
dependencyManagement {
    dependencies {
        imports {
            mavenBom("org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE") {
                bomProperties([
                    "commons-lang3.version": "3.9",
                    "commons-pool2.version": "2.6.1"
                ])
            }
        }
    }
}
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.commons:commons-lang3 -> 3.9
\--- org.apache.commons:commons-pool2 -> 2.6.1

拡張プロパティで宣言する方法もある。

拡張プロパティで指定する例
ext["commons-lang3.version"] = "3.8"
ext["commons-pool2.version"] = "2.6.0"

dependencyManagement {
    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }
    }
}
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.commons:commons-lang3 -> 3.8
\--- org.apache.commons:commons-pool2 -> 2.6.0

依存管理を上書きする

build.gradle
dependencyManagement {
    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }
        dependency "org.apache.commons:commons-lang3:3.9"
    }
}

dependencies {
    implementation "org.apache.commons:commons-lang3"
}
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
\--- org.apache.commons:commons-lang3 -> 3.9

説明

build.gradle
dependencyManagement {
    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }
        dependency "org.apache.commons:commons-lang3:3.9"
    }
}
  • dependency で宣言することで、 BOM で宣言されたバージョンを上書きできる
    • dependency で宣言されたバージョンは、 BOM で宣言されたものよりも優先される
    • imports より上で dependency を宣言しても結果は同じになる
  • この方法なら、 Maven プラグインで出力される pom.xml にもバージョンを上書きする内容が反映される

依存関係を宣言するときに普通にバージョンを指定することで上書きすることもできる。

依存関係の宣言でバージョンを指定する方法
dependencyManagement {
    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }

        dependency "org.apache.commons:commons-lang3:3.9"
        dependency "org.apache.commons:commons-pool2:2.6.1"
    }
}

dependencies {
    implementation "org.apache.commons:commons-lang3"       // バージョン指定しない場合
    implementation "org.apache.commons:commons-pool2:2.6.0" // バージョン指定した場合
}
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.commons:commons-lang3 -> 3.9
\--- org.apache.commons:commons-pool2:2.6.0
  • implementation でバージョンを直接指定した場合は、そのバージョンが採用されている(dependency よりも優先されている)

もし、依存関係の宣言で直接指定したバージョンを無視したい場合は、 overriddenByDependencies オプションに false を設定する。

直接バージョンが指定された場合を無視する
dependencyManagement {
    overriddenByDependencies = false

    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }

        dependency "org.apache.commons:commons-lang3:3.9"
        dependency "org.apache.commons:commons-pool2:2.6.1"
    }
}

dependencies {
    implementation "org.apache.commons:commons-lang3"
    implementation "org.apache.commons:commons-pool2:2.6.0"
}
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.commons:commons-lang3 -> 3.9
\--- org.apache.commons:commons-pool2:2.6.0 -> 2.6.1
  • 直接指定した 2.6.0 は無視されて、 dependency で指定した 2.6.1 が採用された

読み込んだ BOM のプロパティを参照する

build.gradle
dependencyManagement {
    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }
    }
}

task showBomProperty {
    doFirst {
        println "commons-lang3.version = ${dependencyManagement.importedProperties["commons-lang3.version"]}"
    }
}
実行結果
> gradle showBomProperty
...
commons-lang3.version = 3.8.1

説明

build.gradle
task showBomProperty {
    doFirst {
        println "commons-lang3.version = ${dependencyManagement.importedProperties['commons-lang3.version']}"
    }
}
  • 読み込んだ BOM のプロパティは、 dependencyManagement.importedProperties から取得できる

Exclusions

まず、 Spring Boot の BOM を読み込まずに commons-dbcp2 への依存を宣言してみる。

build.gradle
plugins {
    id "java"
}

repositories {
    mavenCentral()
}

dependencies {
    implementation "org.apache.commons:commons-dbcp2:2.5.0"
}
...
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
\--- org.apache.commons:commons-dbcp2:2.5.0
     +--- org.apache.commons:commons-pool2:2.6.0
     \--- commons-logging:commons-logging:1.2

commons-logging への依存が含まれていることが分かる。

次に、 Spring Boot の BOM を読み込んで試してみる。

build.gradle
dependencyManagement {
    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }
    }
}

dependencies {
    implementation "org.apache.commons:commons-dbcp2"
}
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
\--- org.apache.commons:commons-dbcp2 -> 2.5.0
     \--- org.apache.commons:commons-pool2:2.6.0 -> 2.6.2

commons-logging への依存が無くなっていることが分かる。

これは、 Spring Boot の BOM で、 commons-logging への依存が exclusion で指定されている ために起きている。

この挙動を止めたい(BOM で exclusion に指定されていても、依存対象として含めてほしい)場合は、 applyMavenExclusionsfalse を設定する。

build.gradle
dependencyManagement {
    applyMavenExclusions = false

    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }
    }
}

dependencies {
    implementation "org.apache.commons:commons-dbcp2"
}
実行結果
> gradle dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
\--- org.apache.commons:commons-dbcp2 -> 2.5.0
     +--- org.apache.commons:commons-pool2:2.6.0 -> 2.6.2
     \--- commons-logging:commons-logging:1.2

commons-logging への依存が復活した。

configuration ごとに設定する

build.gradle
configurations {
    hoge
    fuga
    piyo
}

dependencyManagement {
    dependencies {
        dependency "org.apache.commons:commons-lang3:3.9"
    }

    hoge {
        dependencies {
            dependency "org.apache.commons:commons-lang3:3.8"
        }
    }

    fuga {
        dependencies {
            dependency "org.apache.commons:commons-lang3:3.8.1"
        }
    }
}

dependencies {
    hoge "org.apache.commons:commons-lang3"
    fuga "org.apache.commons:commons-lang3"
    piyo "org.apache.commons:commons-lang3"
}
実行結果
> gradle dependencies --configuration hoge
...
hoge
\--- org.apache.commons:commons-lang3 -> 3.8

> gradle dependencies --configuration fuga
...
fuga
\--- org.apache.commons:commons-lang3 -> 3.8.1

> gradle dependencies --configuration piyo
...
piyo
\--- org.apache.commons:commons-lang3 -> 3.9

説明

build.gradle
dependencyManagement {
    dependencies {
        dependencies {
            dependency "org.apache.commons:commons-lang3:3.9"
        }
    }

    hoge {
        dependencies {
            dependency "org.apache.commons:commons-lang3:3.8"
        }
    }

    fuga {
        dependencies {
            dependency "org.apache.commons:commons-lang3:3.8.1"
        }
    }
}
  • dependencyManagement の直下に configuration 名でスクリプトブロックを挟むことで、 configuration ごとに依存バージョンを宣言できる
    • BOM のインポートも configuration ごとに可能

依存関係のバージョンを参照する

build.gradle
dependencyManagement {
    dependencies {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
        }
        dependency "org.apache.commons:commons-pool2:2.6.0"
    }

    testImplementation {
        dependencies {
            dependency "org.apache.commons:commons-lang3:3.9"
            dependency "org.apache.commons:commons-pool2:2.6.1"
        }
    }
}

task showManagedVersions {
    doFirst {
        println """\
        |[default]
        |  commons-lang3 = ${dependencyManagement.managedVersions['org.apache.commons:commons-lang3']}
        |  commons-pool2 = ${dependencyManagement.managedVersions['org.apache.commons:commons-pool2']}
        |
        |[testImplementation]
        |  commons-lang3 = ${dependencyManagement.testImplementation.managedVersions['org.apache.commons:commons-lang3']}
        |  commons-pool2 = ${dependencyManagement.testImplementation.managedVersions['org.apache.commons:commons-pool2']}
        |""".stripMargin()
    }
}
実行結果
> gradle showManagedVersions
...
[default]
  commons-lang3 = 3.8.1
  commons-pool2 = 2.6.0

[testImplementation]
  commons-lang3 = 3.9
  commons-pool2 = 2.6.1

説明

build.gradle
    doFirst {
        println """\
        |[default]
        |  commons-lang3 = ${dependencyManagement.managedVersions['org.apache.commons:commons-lang3']}
        |  commons-pool2 = ${dependencyManagement.managedVersions['org.apache.commons:commons-pool2']}
        |
        |[testImplementation]
        |  commons-lang3 = ${dependencyManagement.testImplementation.managedVersions['org.apache.commons:commons-lang3']}
        |  commons-pool2 = ${dependencyManagement.testImplementation.managedVersions['org.apache.commons:commons-pool2']}
        |""".stripMargin()
    }
  • dependencyManagement.managedVersions から、最終的に解決された依存関係のバージョンを参照できる
  • dependencyManagement.<configuration>.managedVersions とすれば、 configuration ごとの情報も参照できる

マルチプロジェクトで使っている場合に注意したほうが良さそうなこと

BOM で宣言されているバージョンを上書きする方法はいくつかあるが、依存関係で直接指定する方法はマルチプロジェクトでは用いないほうが良いかもしれない。

問題の起こる例

次のような構成の Spring Boot アプリケーションを作っていたとする。

プロジェクト構成
|-build.gradle
|-settings.gradle
|
|-common/
| |-src/main/java/
| | `-sample/common/
| |   `-CommonComponent.java
| `-build.gradle
|
`-boot/
  |-src/main/java/
  | `-sample/
  |   `-SampleBootApplication.java
  `-build.gradle
  • common は複数のプロジェクトから参照されるイメージ(ここでは説明を簡単にするため boot プロジェクトだけから参照されている)
  • boot は、 Spring Boot のプロジェクト
CommonComponent.java
package sample.common;

import org.springframework.stereotype.Component;
import org.apache.commons.lang3.ObjectUtils;

@Component
public class CommonComponent {

    public void method(Object obj) {
        System.out.println(ObjectUtils.isEmpty(obj));
    }
}
  • commons-lang3ObjectUtils.isEmpty() を使って、受け取ったオブジェクトが空かどうかを出力している
SampleBootApplication.java
package sample;

import sample.common.CommonComponent;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class SampleBootApplication {

    public static void main(String[] args) {
        try (ConfigurableApplicationContext context = SpringApplication.run(SampleBootApplication.class, args)) {
            CommonComponent common = context.getBean(CommonComponent.class);
            common.method("Hello World");
        }
    }
}
  • こちらは Spring Boot を起動させるクラス
  • 先程の CommonComponent を取り出して実行している

このマルチプロジェクトの各 build.gradle を、次のように記述したとする。

/build.gradle
plugins {
    id "org.springframework.boot" version "2.1.6.RELEASE" apply false
    id "io.spring.dependency-management" version "1.0.8.RELEASE" apply false
}

subprojects {
    apply plugin: "java"
    apply plugin: "io.spring.dependency-management"

    repositories {
        mavenCentral()
    }

    dependencyManagement {
        dependencies {
            imports {
                mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
            }
        }
    }

    sourceCompatibility = 11
    targetCompatibility = 11

    compileJava.options.encoding = "UTF-8"
}
  • 各プロジェクトで共通な設定を subprojects でまとめている
  • Dependency Management Plugin を使って、 Spring Boot の BOM を読み込んでいる
/common/build.gradle
dependencies {
    implementation "org.springframework:spring-context"
    implementation "org.apache.commons:commons-lang3:3.9"
}
  • @Component を使うので、 spring-context の依存を宣言している
  • また、 ObjectUtils を使うので commons-lang3 の依存を宣言している
    • ここで、 commons-lang3 のバージョンには 3.9 を直接指定している
/boot/build.gradle
apply plugin: "org.springframework.boot"

dependencies {
    implementation project(":common")
    implementation "org.springframework.boot:spring-boot-starter"
}
  • Spring Boot アプリになるので、 spring-boot-starter を依存関係に指定している
  • common プロジェクトを参照するので、こちらも依存関係に指定している

この設定でアプリケーションを起動すると、次のようになる。

実行結果
> gradle bootRun
...

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.6.RELEASE)

...
2019-07-06 20:06:16.365  INFO 16428 --- [           main] sample.SampleBootApplication             : Started SampleBootApplication in 0.846 seconds (JVM running for 1.335)
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.commons.lang3.ObjectUtils.isEmpty(Ljava/lang/Object;)Z
        at sample.common.CommonComponent.method(CommonComponent.java:10)
        at sample.SampleBootApplication.main(SampleBootApplication.java:14)

> Task :boot:bootRun FAILED

FAILURE: Build failed with an exception.
  • NoSuchMethodError で落ちた

何が起こった?

各プロジェクトの依存関係を出力すると何が起こったかが分かる。

# common プロジェクトの依存関係
> gradle :common:dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.springframework:spring-context -> 5.1.8.RELEASE
|    ...
\--- org.apache.commons:commons-lang3:3.9

# boot プロジェクトの依存関係
> gradle :boot:dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
+--- project :common
|    +--- org.springframework:spring-context -> 5.1.8.RELEASE
|    |    ...
|    \--- org.apache.commons:commons-lang3:3.9 -> 3.8.1
\--- org.springframework.boot:spring-boot-starter -> 2.1.6.RELEASE
     ...
  • よく見ると、 common プロジェクトの commons-lang33.9 になっているが、 boot プロジェクトから見たときは 3.8.1 になっている
  • ちなみに、問題の起こった ObjectUtils.isEmpty()3.9新規追加されたメソッドになる
  • common プロジェクトがコンパイルされるときは 3.9 を参照しているので問題なくコンパイルはできる
  • しかし、 Spring Boot として起動するときは boot プロジェクトの runtimeClasspath が使用される
  • この結果、起動時に利用される commons-lang33.8.1 になり、当該メソッドがなくて実行時エラーになっていた

なぜバージョンが異なるのか?

/common/build.gradle
dependencies {
    implementation "org.springframework:spring-context"
    implementation "org.apache.commons:commons-lang3:3.9"
}
  • common プロジェクトは、 commons-lang3 のバージョンを直接指定しているので 3.9 になる
/boot/build.gradle
apply plugin: "org.springframework.boot"

dependencies {
    implementation project(":common")
    implementation "org.springframework.boot:spring-boot-starter"
}
  • 一方で、 boot プロジェクトは特に commons-lang3 のバージョンを指定していない
  • したがって、 Spring Boot の BOM で定義されている 3.8.1 が採用されることになる

修正方法

/build.gradle
plugins {
    id "org.springframework.boot" version "2.1.6.RELEASE" apply false
    id "io.spring.dependency-management" version "1.0.8.RELEASE" apply false
}

subprojects {
    apply plugin: "java"
    apply plugin: "io.spring.dependency-management"

    repositories {
        mavenCentral()
    }

    dependencyManagement {
        dependencies {
            imports {
                mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE"
            }

            dependency "org.apache.commons:commons-lang3:3.9"
        }
    }

    ...
}
  • dependencyManagement の中で commons-lang3 のバージョンを指定するように変更
  • これは subprojects 内での設定なので、 commonboot の両プロジェクトに適用される
/common/build.gradle
dependencies {
    implementation "org.springframework:spring-context"
    implementation "org.apache.commons:commons-lang3"
}
  • commonbuild.gradle では、バージョンの指定をやめるように変更
依存関係の確認
# common の依存関係
> gradle :common:dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.springframework:spring-context -> 5.1.8.RELEASE
|    ...
\--- org.apache.commons:commons-lang3 -> 3.9

# boot の依存関係
> gradle :boot:dependencies --configuration runtimeClasspath
...
runtimeClasspath - Runtime classpath of source set 'main'.
+--- project :common
|    ...
|    \--- org.apache.commons:commons-lang3 -> 3.9
\--- org.springframework.boot:spring-boot-starter -> 2.1.6.RELEASE
     ...
  • boot から見た場合も 3.9 になった
実行結果
> gradle bootRun
...
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.6.RELEASE)

...

false
  • 当然、実行してもエラーにはならない

参考

29
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
26