Dev Study
← 解説「Maven: 依存解決(推移依存・nearest wins・dependencyManagement・exclusions・スコープ)」に戻る

サンプルコードで身につける: Maven: 依存解決(推移依存・nearest wins・dependencyManagement・exclusions・スコープ)

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1Boot 雛形の dependency:tree 全文(依存2本 → 72本)

に書いた直接の依存は と spring-boot-starter-webmvc-test の2本だけです。木にすると依存は72本(compile 39、test 33)になり、強調した枝が最も深い5段です。末尾の :compile や :test はで、runtime は0本でした。

$ mvn dependency:tree(Spring Boot 4.1.1 の Maven 雛形、依存は web のみ。全文)コマンド出力
[INFO] com.example:demo:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-webmvc:jar:4.1.1:compile
[INFO] | +- org.springframework.boot:spring-boot-starter:jar:4.1.1:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:4.1.1:compile
[INFO] | | | +- ch.qos.logback:logback-classic:jar:1.5.38:compile
[INFO] | | | | \- ch.qos.logback:logback-core:jar:1.5.38:compile
[INFO] | | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.25.5:compile
[INFO] | | | | \- org.apache.logging.log4j:log4j-api:jar:2.25.5:compile
[INFO] | | | \- org.slf4j:jul-to-slf4j:jar:2.0.18:compile
[INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:4.1.1:compile
[INFO] | | +- jakarta.annotation:jakarta.annotation-api:jar:3.0.0:compile
[INFO] | | \- org.yaml:snakeyaml:jar:2.6:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-jackson:jar:4.1.1:compile
[INFO] | | \- org.springframework.boot:spring-boot-jackson:jar:4.1.1:compile
[INFO] | | \- tools.jackson.core:jackson-databind:jar:3.1.5:compile
[INFO] | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.21:compile
[INFO] | | \- tools.jackson.core:jackson-core:jar:3.1.5:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:4.1.1:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:4.1.1:compile
[INFO] | | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:11.0.24:compile
[INFO] | | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:11.0.24:compile
[INFO] | | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:11.0.24:compile
[INFO] | | \- org.springframework.boot:spring-boot-tomcat:jar:4.1.1:compile
[INFO] | +- org.springframework.boot:spring-boot-http-converter:jar:4.1.1:compile
[INFO] | | +- org.springframework.boot:spring-boot:jar:4.1.1:compile
[INFO] | | | \- org.springframework:spring-context:jar:7.0.9:compile
[INFO] | | \- org.springframework:spring-web:jar:7.0.9:compile
[INFO] | | +- org.springframework:spring-beans:jar:7.0.9:compile
[INFO] | | \- io.micrometer:micrometer-observation:jar:1.17.1:compile
[INFO] | | \- io.micrometer:micrometer-commons:jar:1.17.1:compile
[INFO] | \- org.springframework.boot:spring-boot-webmvc:jar:4.1.1:compile
[INFO] | +- org.springframework.boot:spring-boot-servlet:jar:4.1.1:compile
[INFO] | \- org.springframework:spring-webmvc:jar:7.0.9:compile
[INFO] | +- org.springframework:spring-aop:jar:7.0.9:compile
[INFO] | \- org.springframework:spring-expression:jar:7.0.9:compile
[INFO] \- org.springframework.boot:spring-boot-starter-webmvc-test:jar:4.1.1:test
[INFO] +- org.springframework.boot:spring-boot-starter-jackson-test:jar:4.1.1:test
[INFO] +- org.springframework.boot:spring-boot-starter-test:jar:4.1.1:test
[INFO] | +- org.springframework.boot:spring-boot-test:jar:4.1.1:test
[INFO] | +- org.springframework.boot:spring-boot-test-autoconfigure:jar:4.1.1:test
[INFO] | +- com.jayway.jsonpath:json-path:jar:2.10.0:test
[INFO] | | \- org.slf4j:slf4j-api:jar:2.0.18:compile
[INFO] | +- jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.5:test
[INFO] | | \- jakarta.activation:jakarta.activation-api:jar:2.1.4:test
[INFO] | +- net.minidev:json-smart:jar:2.6.0:test
[INFO] | | \- net.minidev:accessors-smart:jar:2.6.0:test
[INFO] | | \- org.ow2.asm:asm:jar:9.7.1:test
[INFO] | +- org.assertj:assertj-core:jar:3.27.7:test
[INFO] | | \- net.bytebuddy:byte-buddy:jar:1.18.11:test
[INFO] | +- org.awaitility:awaitility:jar:4.3.0:test
[INFO] | +- org.hamcrest:hamcrest:jar:3.0:test
[INFO] | +- org.junit.jupiter:junit-jupiter:jar:6.0.3:test
[INFO] | | +- org.junit.jupiter:junit-jupiter-api:jar:6.0.3:test
[INFO] | | | +- org.opentest4j:opentest4j:jar:1.3.0:test
[INFO] | | | +- org.junit.platform:junit-platform-commons:jar:6.0.3:test
[INFO] | | | \- org.apiguardian:apiguardian-api:jar:1.1.2:test
[INFO] | | +- org.junit.jupiter:junit-jupiter-params:jar:6.0.3:test
[INFO] | | \- org.junit.jupiter:junit-jupiter-engine:jar:6.0.3:test
[INFO] | | \- org.junit.platform:junit-platform-engine:jar:6.0.3:test
[INFO] | +- org.mockito:mockito-core:jar:5.23.0:test
[INFO] | | +- net.bytebuddy:byte-buddy-agent:jar:1.18.11:test
[INFO] | | \- org.objenesis:objenesis:jar:3.3:test
[INFO] | +- org.mockito:mockito-junit-jupiter:jar:5.23.0:test
[INFO] | +- org.skyscreamer:jsonassert:jar:1.5.3:test
[INFO] | | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
[INFO] | +- org.springframework:spring-core:jar:7.0.9:compile
[INFO] | | +- commons-logging:commons-logging:jar:1.3.6:compile
[INFO] | | \- org.jspecify:jspecify:jar:1.0.1:compile
[INFO] | +- org.springframework:spring-test:jar:7.0.9:test
[INFO] | \- org.xmlunit:xmlunit-core:jar:2.11.0:test
[INFO] +- org.springframework.boot:spring-boot-webmvc-test:jar:4.1.1:test
[INFO] | \- org.springframework.boot:spring-boot-web-server:jar:4.1.1:compile
[INFO] \- org.springframework.boot:spring-boot-resttestclient:jar:4.1.1:test
 

2nearest wins を再現する最小の pom.xml(24行)

直接の依存として古い 3.12.0 を書き(強調の前半)、さらに commons-text 1.15.0 を書きます(後半)。commons-text 1.15.0 の は commons-lang3 3.20.0 を要求しているので、同じライブラリに2つの経路で出会います。 を使わないので、版は自分で全部書いています。

pom.xml(l6-deps/nearest。Maven 3.9.16 でビルドできた全文)設定ファイル
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>nearest</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.release>25</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- direct: an OLD commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<!-- commons-text 1.15.0 itself depends on commons-lang3 3.20.0 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.15.0</version>
</dependency>
</dependencies>
</project>
 

34つの pom の dependency:tree: nearest・直接宣言なし・dependencyManagement・exclusions

上の pom と、それを3通りに変えた pom の木です。nearest では を付けると、3.20.0 が omitted for conflict with 3.12.0 と表示されます。直接の宣言を消すと書いていない 3.20.0 が乗り、 に 3.21.0 を書くと version managed from 3.20.0 と出て置き換わります。 では commons-text の下の枝が消えます。

$ mvn dependency:tree(4つのプロジェクト。# の行は補足)コマンド出力
$ mvn dependency:tree # nearest
[INFO] com.example:nearest:jar:1.0.0
[INFO] +- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] \- org.apache.commons:commons-text:jar:1.15.0:compile
$ mvn dependency:tree -Dverbose
[INFO] com.example:nearest:jar:1.0.0
[INFO] +- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] \- org.apache.commons:commons-text:jar:1.15.0:compile
[INFO] \- (org.apache.commons:commons-lang3:jar:3.20.0:compile - omitted for conflict with 3.12.0)
 
# transitive: 12〜16 行目(直接の commons-lang3)を消した pom
$ mvn dependency:tree
[INFO] com.example:transitive:jar:1.0.0
[INFO] \- org.apache.commons:commons-text:jar:1.15.0:compile
[INFO] \- org.apache.commons:commons-lang3:jar:3.20.0:compile
 
# managed: 直接の commons-lang3 を消し、<dependencies> の前に次を足した pom
# <dependencyManagement><dependencies><dependency>
# <groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.21.0</version>
# </dependency></dependencies></dependencyManagement>
$ mvn dependency:tree -Dverbose
[INFO] com.example:managed:jar:1.0.0
[INFO] \- org.apache.commons:commons-text:jar:1.15.0:compile
[INFO] \- org.apache.commons:commons-lang3:jar:3.21.0:compile (version managed from 3.20.0)
 
# excl: commons-text の <version> の後に次を足した pom
# <exclusions><exclusion>
# <groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId>
# </exclusion></exclusions>
$ mvn dependency:tree
[INFO] com.example:excl:jar:1.0.0
[INFO] +- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] \- org.apache.commons:commons-text:jar:1.15.0:compile
 
# nearest をビルドして実行(この組み合わせでは 3.12.0 でも動いた。常に動くとは言えない)
$ mvn -q package && java -cp target/nearest-1.0.0.jar:$(mvn -q dependency:build-classpath -Dmdep.outputFile=/dev/stdout) com.example.Main
Hello From Commons-text
 

4誤解しやすい出力: dependency:analyze はスターターを「未使用」と言う

は、コードが実際に使っているの出どころと pom の宣言を突き合わせます。 の雛形に掛けると、宣言した2本のスターターは Unused declared(書いているのに使っていない)、 や spring-web は Used undeclared(使っているのに書いていない)と出ます。スターターは依存の束で自分ではクラスを持たないからで、この警告どおりに pom を直すとスターターの意味が無くなります。

$ mvn dependency:analyze(Boot 雛形)コマンド出力
$ mvn dependency:analyze
[INFO] --- dependency:3.10.0:analyze (default-cli) @ demo ---
[WARNING] Used undeclared dependencies found:
[WARNING] org.springframework:spring-context:jar:7.0.9:compile
[WARNING] org.junit.jupiter:junit-jupiter-api:jar:6.0.3:test
[WARNING] org.springframework.boot:spring-boot:jar:4.1.1:compile
[WARNING] org.springframework:spring-web:jar:7.0.9:compile
[WARNING] org.springframework.boot:spring-boot-test:jar:4.1.1:test
[WARNING] org.springframework.boot:spring-boot-autoconfigure:jar:4.1.1:compile
[WARNING] Unused declared dependencies found:
[WARNING] org.springframework.boot:spring-boot-starter-webmvc:jar:4.1.1:compile
[WARNING] org.springframework.boot:spring-boot-starter-webmvc-test:jar:4.1.1:test
[INFO] BUILD SUCCESS
 

5うまくいかない場合: 無い座標と、オフライン(-o)のエラー

には、取ってきた と一緒に出どころの帳簿 が置かれます。存在しないを依存に書くと Could not find artifact で失敗し、取れなかった記録 だけが同じ場所に残ります。(オフライン)では、取得済みのものは普通にビルドでき、無いものは「以前に取得していない」という別のエラーになります。どちらのファイルも形式は Resolver の内部のもので(1行目にそう書いてあります)、版で変わりえます。

$ cat _remote.repositories / mvn compile(無い座標)/ mvn -o compileコマンド出力
$ cat ~/.m2/repository/org/apache/commons/commons-text/1.15.0/_remote.repositories
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Sat Oct 03 00:28:46 UTC 2026
commons-text-1.15.0.jar>central=
commons-text-1.15.0.pom>central=
 
# 依存に com.example.nowhere:does-not-exist:1.0 を書いた pom
$ mvn compile
[WARNING] The POM for com.example.nowhere:does-not-exist:jar:1.0 is missing, no dependency information available
[ERROR] Failed to execute goal on project missing: Could not resolve dependencies for project com.example:missing:jar:1.0.0
[ERROR] dependency: com.example.nowhere:does-not-exist:jar:1.0 (compile)
[ERROR] Could not find artifact com.example.nowhere:does-not-exist:jar:1.0 in central (https://repo.maven.apache.org/maven2)
$ find ~/.m2/repository/com/example/nowhere -type f
.../does-not-exist/1.0/does-not-exist-1.0.jar.lastUpdated
.../does-not-exist/1.0/does-not-exist-1.0.pom.lastUpdated
$ cat .../does-not-exist-1.0.jar.lastUpdated
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Sat Oct 03 00:29:14 UTC 2026
https\://repo.maven.apache.org/maven2/.error=
https\://repo.maven.apache.org/maven2/.lastUpdated=1790987354784
 
$ mvn -o -DskipTests package # Boot 雛形。依存は取得済み
[INFO] --- resources:3.5.0:resources (default-resources) @ demo ---
...
[INFO] --- spring-boot:4.1.1:repackage (repackage) @ demo ---
[INFO] BUILD SUCCESS
 
$ mvn -o compile # 無い座標を書いた pom
[ERROR] Cannot access central (https://repo.maven.apache.org/maven2) in offline mode and the artifact com.example.nowhere:does-not-exist:jar:1.0 has not been downloaded from it before.
 

図やコードに出てくる用語(タップで説明)