Dev Study
← 解説「Maven と Gradle がビルドでやっていること」に戻る

サンプルコードで身につける: Maven と Gradle がビルドでやっていること

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

1mvn clean package のログを上から読む

依存を取得済みの状態で を実行したログの抜粋です。--- で始まる行がの1つの実行で、8つが順に動いています(区切りだけの行は落とし、ほかの省略は ... で示しています)。 を呼んでいるのは compiler:compile と compiler:testCompile の2つで、最後の が を包み直しています。

$ ./mvnw -B clean package(Maven 3.9.16 / Boot 4.1.1。行頭は時刻)コマンド出力
13:26:01.946 [INFO] Scanning for projects...
...
13:26:02.144 [INFO] Building demo 0.0.1-SNAPSHOT
...
13:26:02.224 [INFO] --- clean:3.5.0:clean (default-clean) @ demo ---
13:26:02.240 [INFO] Deleting /work/spring-maven/target
13:26:02.242 [INFO] --- resources:3.5.0:resources (default-resources) @ demo ---
13:26:02.262 [INFO] Copying 1 resource from src/main/resources to target/classes
...
13:26:02.266 [INFO] --- compiler:3.15.0:compile (default-compile) @ demo ---
13:26:02.300 [INFO] Recompiling the module because of changed source code.
13:26:02.303 [INFO] Compiling 2 source files with javac [debug parameters release 25] to target/classes
13:26:02.513 [INFO] --- resources:3.5.0:testResources (default-testResources) @ demo ---
...
13:26:02.515 [INFO] --- compiler:3.15.0:testCompile (default-testCompile) @ demo ---
...
13:26:02.518 [INFO] Compiling 1 source file with javac [debug parameters release 25] to target/test-classes
13:26:02.562 [INFO] --- surefire:3.5.6:test (default-test) @ demo ---
...
13:26:02.877 [INFO] Running com.example.demo.DemoApplicationTests
...
13:26:03.668 [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.785 s -- in com.example.demo.DemoApplicationTests
...
13:26:03.679 [INFO] --- jar:3.5.1:jar (default-jar) @ demo ---
13:26:03.754 [INFO] Building jar: /work/spring-maven/target/demo-0.0.1-SNAPSHOT.jar
13:26:03.769 [INFO] --- spring-boot:4.1.1:repackage (repackage) @ demo ---
13:26:03.865 [INFO] Replacing main artifact /work/spring-maven/target/demo-0.0.1-SNAPSHOT.jar with repackaged archive, adding nested dependencies in BOOT-INF/.
13:26:03.865 [INFO] The original artifact has been renamed to /work/spring-maven/target/demo-0.0.1-SNAPSHOT.jar.original
13:26:03.866 [INFO] BUILD SUCCESS
13:26:03.866 [INFO] Total time: 1.926 s
...

2空のローカルリポジトリから何を取ってくるか

を空にしてから を1回実行したログの先頭と、終わったあとの集計です。最初に親の を取りに行き、そこから合計 533 ファイルを取得しました。JAR は171本ありますが実行時に使うのは34本で、残りはテスト用の依存と、compiler や などのプラグイン、そのプラグイン自身の依存です。

ローカルリポジトリを空にしてからの ./mvnw -B package(ログの先頭と末尾)と、終了後の ~/.m2/repository の集計コマンド出力
13:19:30.840 [INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/4.1.1/spring-boot-starter-parent-4.1.1.pom
13:19:31.005 [INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/4.1.1/spring-boot-starter-parent-4.1.1.pom (14 kB at 87 kB/s)
13:19:31.015 [INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-dependencies/4.1.1/spring-boot-dependencies-4.1.1.pom
13:19:31.081 [INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-dependencies/4.1.1/spring-boot-dependencies-4.1.1.pom (141 kB at 2.1 MB/s)
...
13:21:10.520 [INFO] BUILD SUCCESS
13:21:10.520 [INFO] Total time: 01:39 min
 
Downloaded from の行数 533(3回とも同じ)
~/.m2/repository のファイル数 1,428
うち JAR 171
うち POM 362
~/.m2/repository の大きさ 80,852 KB
実行時に使う JAR 34
テストまで含めたクラスパス 71

3Gradle のタスク一覧と、変更なしの2回目

同じアプリを 9.7.1 でビルドしたときの出力です。何も変えずにもう一度実行すると、すべて になってテストも走りません(363ms)。 は同じ「変更なし」でもテストを毎回実行し、2.03〜2.05 秒かかりました。

./gradlew --console=plain clean build と、変更なしでの build(デーモン稼働中。$ の行は再構成)コマンド出力
$ ./gradlew --console=plain clean build
> Task :clean
> Task :compileJava
> Task :processResources
> Task :classes
> Task :resolveMainClassName
> Task :bootJar
> Task :jar
> Task :assemble
> Task :compileTestJava
> Task :processTestResources NO-SOURCE
> Task :testClasses
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
> Task :test
> Task :check
> Task :build
 
BUILD SUCCESSFUL in 1s
8 actionable tasks: 8 executed
Consider enabling configuration cache to speed up this build: https://docs.gradle.org/9.7.1/userguide/configuration_cache_enabling.html
 
$ ./gradlew --console=plain build
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :resolveMainClassName UP-TO-DATE
> Task :bootJar UP-TO-DATE
> Task :jar UP-TO-DATE
> Task :assemble UP-TO-DATE
> Task :compileTestJava UP-TO-DATE
> Task :processTestResources NO-SOURCE
> Task :testClasses UP-TO-DATE
> Task :test UP-TO-DATE
> Task :check UP-TO-DATE
> Task :build UP-TO-DATE
 
BUILD SUCCESSFUL in 363ms
7 actionable tasks: 7 up-to-date
Consider enabling configuration cache to speed up this build: https://docs.gradle.org/9.7.1/userguide/configuration_cache_enabling.html

4ビルドが終わっても残る JVM と、--no-daemon の実際

Gradle はビルドのあとも(常駐の )を残します。起動33秒後に見た待機中の は 841,768 KB でした(1回の観測で、設定や稼働時間で変わります)。 を付けても、この構成では「使い捨てのデーモン」が別に起動され、ビルドの最後に止められました。

gradlew --status / ps / --no-daemon を付けた clean build の抜粋(Gradle 9.7.1。$ の行は再構成)コマンド出力
$ ./gradlew --status
PID STATUS INFO
9746 IDLE 9.7.1
 
$ ps -eo pid,rss,etime,args | grep gradle
9746 841768 00:33 /opt/java/openjdk/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED ...
 
$ ./gradlew --console=plain --no-daemon clean build
To honour the JVM settings for this build a single-use Daemon process will be forked. For more on this, please refer to https://docs.gradle.org/9.7.1/userguide/gradle_daemon.html#sec:disabling_the_daemon in the Gradle documentation.
Daemon will be stopped at the end of the build
> Task :clean
> Task :compileJava
...
BUILD SUCCESSFUL in 4s
8 actionable tasks: 8 executed
...
 
$ ./gradlew --status
No Gradle daemons are running.

5npm・Cargo と並べる: 道具と依存をどこに置くか

空の状態から1回ビルドしたあとに、手元に何がどれだけ置かれたかを並べた実測値です。Maven と Gradle はプロジェクトの外の共有の場所に置き、npm はプロジェクトの中の node_modules に展開し、 はソースを取ってきて にコンパイル結果を置きます。数え方がそれぞれ違うので、本数どうしの大小は比べられません。

初回ビルド後に手元に置かれたもの(同じ最小アプリ。Maven 3.9.16 / Gradle 9.7.1 / npm 11.19.0 / cargo 1.98.1)表
道具 置き場所 取ってきたもの 大きさ
Maven ~/.m2/repository 1,428 ファイル(JAR 171・POM 362) 80,852 KB
~/.m2/wrapper Maven 本体(mvnw が取得) 11M(du -h の表示)
Gradle ~/.gradle/caches 1,278 ファイル(JAR 98) 97,512 KB
~/.gradle/wrapper Gradle の配布物(gradlew が取得) 165M(du -h の表示)
npm プロジェクト内の node_modules 389 パッケージ・9,976 ファイル 171,276 KB
(開発用の依存を含む)
Cargo cargo のレジストリ Cargo.lock で 55 パッケージ 51,928 KB
プロジェクト内の target コンパイル結果(release) 117,504 KB

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