概要: GradleはJavaプロジェクトのビルド自動化ツールで、Spring Bootアプリケーションの実行やパッケージ化に役立ちます。本記事ではbootRun、bootJar、bootBuildImageなどの主要タスクの使い方から、Dockerイメージ作成の方法までを解説します。
Gradleの基本:bootRunやbootJarとは何か?
Spring Boot Gradleプラグインが提供する主要タスク
Spring BootでGradleを使う場合、org.springframework.bootプラグインを適用すると、開発に必要なタスクが自動的に追加されます。代表的なのは、アプリを直接起動するbootRun、実行可能JARを作成するbootJar、Dockerイメージを生成するbootBuildImageの3つです。
このプラグインはJavaプラグインを前提として動作し、標準のjarタスクを拡張する形でbootJarが機能します。具体的には、Spring Bootプラグイン適用時に標準のjarタスクはplainというクラシファイア付きに変更され、bootJarが実質的なパッケージングを担います。
| タスク名 | 役割 | 主な用途 |
|---|---|---|
bootRun |
ソースコードからアプリを直接起動 | 開発中の動作確認 |
bootJar |
実行可能なfat JARを作成 | 本番用成果物の生成 |
bootBuildImage |
Dockerfile不要でOCIイメージを作成 | コンテナデプロイ向け |
GradleでSpring Bootアプリを扱う基本は、これら3つのタスクを目的に応じて使い分けることです(出典:Spring Boot公式ドキュメント「Reacting to the Java Plugin」)。
実行可能JAR(fat JAR)の仕組み
bootJarが生成するのは、実行可能なuber JAR(fat JAR)です。通常のJARと異なり、アプリのクラスだけでなく依存ライブラリもすべて1つのファイルに含まれます。
内部構造は、アプリのクラスがBOOT-INF/classes、依存JARがBOOT-INF/libに配置され、Spring Bootの起動ローダーがこれらを読み込んでアプリを起動します。メインクラスはMain-ClassとStart-Classがマニフェストに自動設定されるため、手動でメインクラスを指定する必要はありません。
成果物はbuild/libs/にプロジェクト名-バージョン.jarとして出力され、./gradlew buildを実行するとassembleタスク経由でbootJarも自動実行されます(出典:Spring Boot公式ドキュメント「Reacting to the Java Plugin」)。
Gradle WrapperとJavaバージョンの関係
Spring Bootプロジェクトを扱う前に、Gradle Wrapperの利用が公式推奨であることを理解しておきましょう。Wrapperを使うと、プロジェクトごとにGradleのバージョンを固定でき、チームやCI環境で同じビルド環境を再現できます。
Gradleを実行するにはJDK 17以上が必要です。ただし、Gradle自体を実行するJDKと、Spring Bootアプリをコンパイル・実行するJavaバージョンは別物です。Java Toolchainsを使えば、Gradleの実行環境とプロジェクトのJava環境を分離できます。
Spring Boot 4.xはGradle 8.14以降とGradle 9.xをサポートしているため、Gradle 9.6.1との組み合わせに問題はありません(出典:Gradle公式ドキュメント「Compatibility Matrix」)。
Spring Boot Gradleプラグインは、bootRun・bootJar・bootBuildImageの3タスクを中心に、開発から本番デプロイまでを1つのビルドツールで完結させます。
bootRunの正しい使い方と終わらない問題の対処法
bootRunの基本的な使い方
bootRunは、ビルドせずにソースコードとruntime classpathからアプリを直接起動する開発用タスクです。コマンドは./gradlew bootRunで、コードの変更を反映しながら素早く動作確認できます。
起動時に引数を渡したい場合は、--argsオプションを使います。例えばポートを変更するなら./gradlew bootRun --args='--server.port=8081'と指定します。また、applicationプラグインを適用している場合、mainClassNameやapplicationDefaultJvmArgsの設定をbootRunが自動的に引き継ぎます。
- コマンド:
./gradlew bootRun - 引数指定:
./gradlew bootRun --args='--server.port=8081' - テスト用起動:
./gradlew bootTestRun(テストソースセットで起動)
開発中はこのタスクを使うことで、JARファイルを作る手間を省いて即座にアプリの挙動を確認できます(出典:Spring Boot公式ドキュメント「Reacting to the Java Plugin」)。
bootRunが終わらない理由と対処法
bootRunはアプリを起動したまま待機し続けるタスクです。そのため「コマンドが終わらない」と感じるのは、実は正常な動作です。Spring BootアプリはWebサーバーを内蔵しており、停止命令があるまでプロセスが動き続けます。
終了するには、ターミナルでCtrl + Cを押してプロセスを中断します。もし「タスクが終了しない」のではなく「ビルドが失敗する」「アプリが起動しない」という場合は、ポート競合や設定ミスが原因の可能性があります。その場合は--args='--server.port=8081'で別ポートを指定するか、ログを確認して原因を特定しましょう。
また、bootRunは開発専用です。本番環境ではbootJarで生成した実行可能JARをjava -jarで起動するのが正しい使い方です(出典:Spring Boot公式ドキュメント「Reacting to the Java Plugin」)。
bootRunと通常のjava -jar実行の違い
bootRunと実行可能JARを使った起動は、起動方法と利用シーンが異なります。bootRunはソースコードから直接起動するため、ビルド工程をスキップして素早く起動できる反面、本番環境での利用は想定されていません。
実行可能JARはbootJarで生成された成果物をjava -jar application.jarで起動します。こちらはビルド済みの成果物を使うため、どの環境でも同じ動作を再現できます。
| 比較項目 | bootRun | java -jar |
|---|---|---|
| ビルド工程 | 不要(ソースから直接起動) | 必要(bootJarで事前に生成) |
| 主な利用シーン | 開発中の動作確認 | 本番・検証環境での起動 |
| 起動速度 | ビルド分だけ速い | JAR生成後に起動 |
| 環境再現性 | 開発環境に依存 | どの環境でも同じ |
bootRunは「終わらないタスク」ではなく、アプリを起動し続ける開発用タスクです。停止するにはCtrl + Cを使い、本番ではbootJarで生成したJARをjava -jarで起動します。
bootJarとbootWarの違い:実行可能JARの作成方法
bootJarとbootWarの使い分け
bootJarは実行可能なJARファイルを、bootWarは実行可能なWARファイルを作成するタスクです。どちらを使うかは、アプリのデプロイ方法によって決まります。
JARはSpring Bootの組み込みWebサーバー(Tomcatなど)を含むため、java -jarだけで起動できる自己完結型の成果物です。一方、WARは外部のServletコンテナ(TomcatやWildFlyなど)にデプロイして動かす形式で、既存のアプリケーションサーバー環境を利用する場合に選択します。
Spring BootではJAR形式がデフォルトであり、クラウド環境やコンテナデプロイではJARが主流です。
bootJar:組み込みサーバーを含む自己完結型JARを作成bootWar:外部ServletコンテナにデプロイするWARを作成
(出典:Spring Boot公式ドキュメント「Reacting to the Java Plugin」)
bootJarで実行可能JARを作成する手順
実行可能JARの作成は、Spring Boot Gradleプラグインを適用するだけでほぼ完了します。特別な設定を追加しなくても、メインクラスの自動検出とマニフェスト設定が行われます。
build.gradleにSpring Bootプラグインを適用する./gradlew bootJarを実行するbuild/libs/プロジェクト名-バージョン.jarが生成されるjava -jar 生成されたJARファイルで起動確認する
JARの内部は、アプリのクラスがBOOT-INF/classes、依存ライブラリがBOOT-INF/libに配置されます。また、./gradlew buildを実行すると、assembleタスク経由でbootJarも自動実行されるため、通常のビルドフローに組み込まれています(出典:Spring Boot公式ドキュメント「Reacting to the Java Plugin」)。
レイヤードJARの仕組みと利点
Spring BootはJARをレイヤ分割する仕組みをサポートしており、Dockerイメージの効率的な構築に役立ちます。デフォルトでは、依存ライブラリ・Spring Bootローダー・スナップショット依存・アプリコードの4レイヤに分かれます。
| レイヤ名 | 内容 | 変更頻度 |
|---|---|---|
| dependencies | リリース済みの依存ライブラリ | 低 |
| spring-boot-loader | Spring Boot起動コード | 低 |
| snapshot-dependencies | スナップショット依存 | 中 |
| application | アプリのクラス・リソース | 高 |
レイヤ分割を使うと、変更頻度の低い依存ライブラリをDockerイメージのキャッシュとして再利用できるため、コード変更時のイメージ再構築が高速になります。レイヤの抽出にはjava -Djarmode=tools -jar app.jar extract --layersコマンドを使用します(出典:Spring Boot公式ドキュメント「Efficient Container Images」)。
bootJarは組み込みサーバーを含む自己完結型JARを作成し、コンテナデプロイの標準形式です。レイヤードJARを活用するとDockerイメージ構築の効率が大幅に向上します。
Dockerイメージ作成はbootBuildImageとDockerfileの2つの方法
bootBuildImageでDockerfile不要のイメージ作成
bootBuildImageは、Dockerfileを書かずに1コマンドでOCIイメージを作成できるSpring Bootの公式機能です。Cloud Native Buildpacks(CNB)を使い、Paketo buildpacksが自動的にJREを組み込んで本番向けイメージを生成します。
実行コマンドは./gradlew bootBuildImageで、デフォルトのイメージ名はdocker.io/library/プロジェクト名:バージョンです。イメージ名を指定する場合は--imageName=example.com/library/my-app:v1のようにオプションを付けます。ビルドにはローカルでDockerデーモンが起動している必要があります。
- コマンド:
./gradlew bootBuildImage - イメージ名指定:
./gradlew bootBuildImage --imageName=example.com/my-app:v1 - 前提条件:ローカルでDockerデーモンが起動していること
生成されたイメージはレイヤードJARとSBOM(ソフトウェア部品表)を含む本番向け構成ですが、デフォルトのUbuntuベースのためイメージサイズは約400MBと大きめです(出典:Spring Boot公式ドキュメント「Cloud Native Buildpacks」)。
Dockerfileによる手動構築とマルチステージビルド
Dockerfileを使う方法は、より細かい制御ができる反面、効率的なイメージを作るための知識が必要です。単純にfat JARをコピーするだけでは、アプリコードと全依存が同一レイヤになり、コード変更のたびに全レイヤを再構築することになります。
公式推奨はレイヤードJARを抽出してからDockerイメージにコピーするマルチステージビルドです。まずビルダーステージでjava -Djarmode=tools -jar application.jar extract --layers --destination extractedを実行してJARをレイヤ分割し、実行ステージで各レイヤを個別にコピーします。これにより、変更頻度の低い依存ライブラリはDockerのキャッシュを活用できます。
- ビルダーステージでJARをレイヤ抽出する
- 実行ステージで各レイヤを個別にコピーする
- 軽量なJREイメージをベースに使用する
ENTRYPOINT ["java", "-jar", "application.jar"]で起動する
(出典:Spring Boot公式ドキュメント「Dockerfiles」)
2つの方法の比較と選び方
どちらの方法を選ぶかは、プロジェクトの要件とチームのスキルセットによって判断します。bootBuildImageは手軽さが最大の利点で、Dockerの知識が少なくても本番向けイメージを生成できます。
| 比較項目 | bootBuildImage | Dockerfile |
|---|---|---|
| Dockerfileの必要性 | 不要 | 必要 |
| 設定の柔軟性 | 低い(builder設定に依存) | 高い(自由にカスタマイズ可能) |
| イメージサイズ | 約400MB(Ubuntuベース) | 軽量JRE選択で約200〜400MBに調整可能 |
| OSパッケージの追加 | 難しい | 容易 |
| 学習コスト | 低い | 高い |
手軽に始めるならbootBuildImage、イメージサイズや構成を細かく最適化したいならDockerfileという使い分けが現実的です(出典:Spring Boot公式ドキュメント「Container Images」)。
bootBuildImageはDockerfile不要で本番向けイメージを1コマンド生成、DockerfileはレイヤードJARと軽量JREを組み合わせることでイメージサイズと再構築効率を最適化できます。
GradleでSpring Bootをパッケージ化する際の注意点
バージョン互換性の確認ポイント
Spring BootをGradleでパッケージ化する際、JDK・Gradle・Spring Bootプラグインの3つのバージョン互換性を最初に確認する必要があります。Gradleを実行するにはJDK 17以上が必要で、Spring Boot 4.xはGradle 8.14以降とGradle 9.xをサポートしています。
特に注意したいのは、「Gradleを実行するJDK」と「アプリをコンパイル・実行するJavaバージョン」は別物という点です。Java Toolchainsを使えば、Gradleの実行環境とは異なるJavaバージョンでプロジェクトをビルドできます。新規プロジェクトでは、最新安定版の組み合わせ(Gradle 9.6.1 + Spring Bootプラグイン4.1.0)を選ぶのが確実です。
- Gradle実行環境:JDK 17以上が必要
- Spring Boot 4.x:Gradle 8.14+ / 9.xをサポート
- Java Toolchainsで実行環境とビルド対象のJavaを分離可能
(出典:Gradle公式ドキュメント「Compatibility Matrix」、Spring Boot 4.0 Release Notes)
標準jarタスクの変更に注意
Spring Boot Gradleプラグインを適用すると、標準のjarタスクの動作が変わります。具体的には、jarタスクが生成する成果物にplainというクラシファイアが付き、bootJarがメインのパッケージングタスクになります。
そのため、既存のGradleプロジェクトにSpring Bootプラグインを追加した場合、build/libs/にプロジェクト名-バージョン.jar(bootJar)とプロジェクト名-バージョン-plain.jar(標準jar)の2つが生成されることがあります。通常はbootJarの成果物をデプロイに使用しますが、標準jarと混同しないよう注意が必要です。
また、./gradlew buildを実行すると、assembleタスク経由でbootJarも自動実行されるため、明示的にbootJarを指定しなくても実行可能JARが生成されます(出典:Spring Boot公式ドキュメント「Reacting to the Java Plugin」)。
コンテナ用JVM設定のベストプラクティス
DockerコンテナでSpring Bootアプリを実行する場合、JVMのメモリ設定をコンテナ環境に合わせることが重要です。Java 10以降はUseContainerSupportがデフォルトで有効なため、コンテナのメモリ制限をJVMが自動認識します。
推奨される設定は、固定のヒープサイズではなく-XX:MaxRAMPercentage=75.0のようにコンテナのメモリ制限に対する割合で指定する方法です。これにより、コンテナのメモリ制限が変わってもJVMが適切に追従します。
- 推奨:
-XX:MaxRAMPercentage=75.0(コンテナメモリの75%を上限に使用) - Java 10以降:
UseContainerSupportがデフォルト有効 - セキュリティ:非rootユーザーでアプリを実行する
また、コンテナイメージでは非rootユーザーでアプリを実行することがセキュリティ上のベストプラクティスです(出典:Spring Boot公式ドキュメント「Efficient Container Images」)。
パッケージ化の前にJDK・Gradle・Spring Bootプラグインの互換性を確認し、標準jarタスクの変更を理解した上で、コンテナ環境では割合ベースのメモリ設定と非root実行を適用します。
まとめ
よくある質問
Q: bootRunとは何ですか?
A: bootRunはSpring Boot Gradleプラグインが提供するタスクで、ビルドせずにソースとruntime classpathから直接アプリケーションを起動します。開発時に変更をすぐ反映させたい場合に便利です。
Q: bootRunが終わらないのはなぜですか?
A: bootRunはWebアプリケーションなどのサーバープロセスを起動するため、明示的に停止するまで終了しません。開発中は正常な動作であり、停止する場合はCtrl+Cを押すか、コマンドを別途実行してプロセスを終了させる必要があります。
Q: bootJarとbootWarの違いは何ですか?
A: bootJarは実行可能なuber JAR(fat JAR)を作成するタスクで、主にWebアプリケーション以外の実行可能JARを作成する際に使用します。bootWarは実行可能なWARファイルを作成するタスクで、主に外部のサーブレットコンテナにデプロイするためのWARファイルを作成する際に使用します。
Q: bootBuildImageでDockerイメージを作成するにはどうすればよいですか?
A: 「./gradlew bootBuildImage」コマンドを実行します。Cloud Native Buildpacks(CNB)を使用して、Dockerfileを書かずにOCIイメージを直接作成できます。デフォルトのbuilderはPaketo buildpacksで、Dockerデーモンがローカルで起動している必要があります。
Q: DockerfileでSpring BootアプリをDockerイメージ化する際のポイントは?
A: 実行可能JARをそのままコピーする方法もありますが、Spring Bootのレイヤリング機能を利用することが公式推奨です。JARは「dependencies」「spring-boot-loader」「snapshot-dependencies」「application」の4つのレイヤに分割でき、アプリコードの変更時に依存ライブラリを含むレイヤを再送信する必要がなく、push/pull効率が向上します。
