VS Code + Docker + Gemini CLI で Java 開発(Maven 版)
はじめに
この記事は「VS Code + Docker + Gemini CLI で Java 開発(Gradle 版)」の続きです。
ここでは、前回用意した Gradle プロジェクトを Apache Maven プロジェクトへ移行したので、これについて説明します。
前回は、開発コンテナで Gemini CLI を使えるようにし、Gemini を使ってシンプルな Java プロジェクトを Gradle プロジェクトへ移行しました。今回は、VS Code と Docker を使った Maven プロジェクトの Java プログラム開発についての解説となります。
Gemini CLI は使える環境になっているだけで、そちらの解説はあまりしていません。あらかじめ、ご了承ください。
サンプルコード
GitHub にサンプルコードを用意したので、先に紹介しておきます。
java-app003-00 のタグをつけてあります。
タグ | 説明 |
---|---|
java-app003-00 | 今回、解説するもの |
java-app002-00 | 前回のもの |
利用するには開発コンテナの環境を用意するのが手軽です。リポジトリ内の dvc-java-gemini/README.md
の説明にしたがって環境構築をしてください。
開発コンテナ用のファイルについては、前回の記事の「Gemini CLI 向け Dev Container のセットアップ」の解説を参照してください。
Apache Maven とは
最初に、今回利用する Apache Maven について、簡単に説明をします。
Maven は、Java プロジェクトで広く利用されているビルド自動化ツールであり、プロジェクト管理ツールでもあります。その主な目的は、開発者がプロジェクトのビルド、レポート作成、ドキュメント生成を簡単かつ標準的な方法で行えるようにすることです。
Maven は次の 3 つの主要な概念に基づいて構築されています。
- プロジェクトオブジェクトモデル (POM)
- 依存関係管理
- ビルドライフサイクル
Maven プロジェクトでは、**プロジェクトオブジェクトモデル (POM)**により、プロジェクトの構成が一目でわかります。具体的には、POM を表現するための pom.xml
というファイルがあり、これに、プロジェクトの依存関係、プラグイン、ゴール、ビルドプロファイルなど、すべての設定情報を集約します。
また、pom.xml
にプロジェクトが必要とするライブラリを記述するだけで、依存関係管理が簡単にできるようになっています。この情報を使って、Maven がセントラルリポジトリから必要な JAR ファイルを自動的にダウンロードして管理します。手動で JAR ファイルを管理する手間を省き、バージョン競合の問題を解決しやすくします。
pom.xml
の記述にあたっては、ビルドライフサイクルという重要な概念についての理解が不可欠です。これは、プロジェクトをビルドし、配布するための一連の標準化されたフェーズ(工程)を定義します。フェーズはあらかじめ決められているという点がポイントです。これにより、どんな Maven プロジェクトでも同じコマンドで一貫したビルドプロセスを実行できます。
ビルドライフサイクル
Maven のライフサイクルは、ビルドの各ステップを定義した「フェーズ (Phase)」の集まりです。特定のフェーズを実行すると、そのフェーズに至るまでのすべてのフェーズが順番に実行されます。
Maven には主に 3 つの組み込みライフサイクルがあります。
-
default
: プロジェクトのビルドとデプロイ -
clean
: ビルドで生成されたファイル(target
ディレクトリなど)を削除 -
site
: プロジェクトのドキュメントサイトを生成
開発者が pom.xml
を記述するときには、「どのライフサイクルの、どのフェーズで、どういった処理を実行するのか」を意識して設計するということになります。
default ライフサイクル
開発時に一番良く使用するのは、default
ライフサイクルです。
このライフサイクルの主要なフェーズは次の順番で構成されています。ここでは、代表的なものを示しています。
-
validate
: プロジェクトが正しいか、必要な情報がすべて利用可能か検証 -
compile
: プロジェクトのソースコードをコンパイル -
test
: コンパイルされたソースコードを、適切な単体テストフレームワーク(JUnit など)でテスト -
package
: テスト済みのコードを、pom.xml
で定義された形式(JAR, WAR など)にパッケージング -
verify
: パッケージが有効であり、品質基準を満たしているかチェック -
install
: パッケージをローカルリポジトリにインストール -
deploy
: 完成したパッケージのデプロイ
例えば、./mvnw install
というコマンドを実行すると、Maven は default
ライフサイクルの validate
から install
までのすべてのフェーズを順番に実行します。つまり、コードの検証、コンパイル、テスト、パッケージング、そしてローカルリポジトリへのインストールが一度に行われるのです。
このように、ライフサイクルという概念があるおかげで、開発者は複雑なビルド手順を覚えることなく、標準化されたコマンドでプロジェクトを管理できます。
リポジトリ
Maven の強力な依存関係管理機能は、「リポジトリ (Repository)」という仕組みによって支えられています。リポジトリは、プロジェクトの成果物(JAR ファイルなど)やプラグインを保管し、共有するための場所です。
Maven は主に次の役割の異なる 2 種類のリポジトリを連携させて利用します。
- ローカルリポジトリ
- リモートリポジトリ
依存関係を解決する際、Maven はまずローカルリポジトリを探し、そこに見つからなければリモートリポジトリに問い合わせに行きます。
ローカルリポジトリ
ローカルリポジトリは、開発者自身のコンピュータ上に作成される、ライブラリやプラグインの一時的な保管場所(キャッシュ)です。デフォルトでは、ユーザーのホームディレクトリ配下の .m2/repository
に作られます。
一度リモートリポジトリからダウンロードされた依存ライブラリは、すべてこのローカルリポジトリに保存されます。次回以降、同じライブラリが必要になった場合は、インターネットにアクセスすることなく、ローカルリポジトリから即座に取得されます。これにより、ビルドの高速化とオフラインでの作業が可能になります。
また、./mvnw install
コマンドを実行すると、ビルドしたプロジェクトの成果物(JAR ファイル)がこのローカルリポジトリにインストールされます。これにより、同じマシン上の他のプロジェクトから依存関係として参照できるようになりますが、チームの他のメンバーと共有するためにはリモートリポジトリへのデプロイが必要です。
リモートリポジトリ
リモートリポジトリは、ネットワーク経由でアクセスされるサーバー上のリポジトリです。チーム内での成果物の共有や、オープンソースライブラリの配布に利用されます。リモートリポジトリは、その公開範囲によっていくつかの種類に分けられます。
リポジトリ | 説明 |
---|---|
セントラルリポジトリ | Maven コミュニティが公式に提供するデフォルトのリモートリポジトリ |
その他のパブリックリポジトリ | セントラルリポジトリ以外にも、特定の目的のために利用できる公開リポジトリ |
プライベートリポジトリ | 企業や組織内で独自に運用されるリポジトリ |
これらのリポジトリが連携することで、Maven は効率的かつ安定した依存関係管理を実現しています。
セントラルリポジトリには、世界中のオープンソースライブラリが集約されています。pom.xml
に依存関係を記述するだけで、Maven が自動的にここからライブラリをダウンロードします。
その他のパブリックリポジトリは、特定のベンダーが提供するライブラリでセントラルリポジトリには登録されていないライブラリを利用したい場合に使用します。別の公開リポジトリを指定するには、pom.xml
に <repositories>
タグを追加します。代表的なものには、Spring、JBoss、Google のリポジトリなどがあります。
- Spring Repository: https://repo.spring.io/release
- JBoss Repository: https://repository.jboss.org/nexus/content/groups/public/
- Google's Maven Repository: https://maven.google.com/
プライベートリポジトリには、企業や組織内で独自に運用される非公開のリポジトリです。主な目的は次の通りです。
- 自社で開発したライブラリや成果物を、組織内で安全に共有すること
- 外部のパブリックリポジトリのプロキシとして機能させ、ダウンロードしたライブラリをキャッシュすることで、ビルドの高速化と安定化を図ること
- 利用するライブラリを組織内で承認されたものだけに限定し、セキュリティを管理すること
プライベートリポジトリは、GitLab のパッケージレジストリ機能 で提供することができます。Sonatype Nexus や JFrog Artifactory といった専用のソフトウェアで構築することもできます。関連する URL のリストを次に示します。
java-app003 の解説
java-app003
は、java-app002
の Gradle プロジェクトを Maven へ移行したものです。基本的なコンソールアプリケーションである点は同じですが、開発体験を向上させるための様々な機能が追加されています。
- Maven によるビルド管理:
pom.xml
を中心に、依存関係の管理やビルドプロセスが定義されています。 - 静的コード解析: Checkstyle を導入し、Google Java Style Guide に基づくコード規約を適用しています。
- ドキュメント生成: Javadoc と Maven Site Plugin を活用し、API ドキュメントやプロジェクト情報をまとめた Web サイトを生成できます。
- テストレポート: Maven Surefire Report Plugin により、JUnit のテスト結果を HTML で閲覧できます。
- VS Code でのデバッグ:
java-app003.code-workspace
にデバッグ用の起動構成が定義されており、VS Code から直接デバッグ実行が可能です。
Maven プロジェクトのフォルダ構成
java-app003
のフォルダ構成は、標準的な Maven プロジェクトのレイアウトに従っています。これは、前回解説した Gradle プロジェクト (java-app002
) と多くの点で共通していますが、ビルドツール固有の違いも存在します。
共通点:ソースコードの配置
まず、アプリケーションのソースコードやリソースファイルの配置場所は、Maven と Gradle で全く同じです。これは両ツールが「設定より規約」の思想に従い、同じディレクトリ構造を標準としているためです。
パス(配置場所) | 説明 |
---|---|
src/main/java |
アプリケーション本体の Java ソースコードを配置 |
src/main/resources |
logback.xml のような、ビルド時にクラスパスに含めたい設定ファイルなどを配置 |
src/test/java |
JUnit などで記述されたテストコードを配置 |
src/test/resources |
テスト実行時に利用する設定ファイルなどを配置 |
この規約のおかげで、ビルドツールを Maven から Gradle へ(あるいはその逆へ)移行する際に、ソースコードの移動が不要になります。
相違点:ビルド関連ファイルの比較
違いが表れるのは、プロジェクトのビルド設定や、ビルドツール自体を管理するためのファイルです。
目的 | Maven (java-app003 ) |
Gradle (java-app002 ) |
---|---|---|
プロジェクト定義 | pom.xml |
build.gradle / settings.gradle
|
ラッパー実行スクリプト |
mvnw , mvnw.cmd
|
gradlew , gradlew.bat
|
ラッパー設定 | .mvn/wrapper/ |
gradle/wrapper/ |
以下に java-app003
の構造を示します。Gradle プロジェクトの構造と見比べると、違いがより明確になるでしょう。
java-app003/
├── .mvn/
│ └── wrapper/
│ └── maven-wrapper.properties # Maven Wrapper の設定ファイル
├── src/
│ ├── main/
│ │ ├── java/ # アプリケーションのソースコード
│ │ │ └── internal/dev/App.java
│ │ └── resources/ # 設定ファイルなど
│ │ └── logback.xml
│ └── test/
│ └── java/ # テストコード
│ └── internal/dev/AppTest.java
├── .gitignore # Git の無視ファイル設定
├── google_checks.xml # Checkstyle の設定ファイル
├── java-app003.code-workspace # VS Code のワークスペース設定
├── mvnw # Maven Wrapper の実行スクリプト (Linux/macOS)
├── mvnw.cmd # Maven Wrapper の実行スクリプト (Windows)
├── pom.xml # Maven のプロジェクト設定ファイル
└── README.md # プロジェクトの説明書
プロジェクト定義ファイル:
Maven では pom.xml
という XML ファイルに、プロジェクトの依存ライブラリ、ビルド設定、プラグインなど、すべての情報を集約して記述します。
一方、Gradle では build.gradle
(または build.gradle.kts
) という Groovy や Kotlin で書かれたスクリプトファイルにビルドロジックを記述し、settings.gradle
でプロジェクトの基本的な設定を管理することが一般的です。
ラッパー (Wrapper) と JDK:
どちらのツールも、開発環境に特定のバージョンのビルドツールがインストールされていなくても、プロジェクトで定義されたバージョンを自動的にダウンロードして利用するための「ラッパー」機能を提供します。
Maven では、実行スクリプトが mvnw
と mvnw.cmd
、設定ファイルが .mvn/wrapper/
ディレクトリに配置されます。
Gradle では、実行スクリプトが gradlew
と gradlew.bat
、設定ファイルが gradle/wrapper/
ディレクトリに配置されます。
ここで、ビルドに必要な JDK の扱いには違いがあります。
Maven Wrapper は JDK を管理しません。mvnw
を実行する前に、適切なバージョンの JDK があらかじめインストールされ、JAVA_HOME
環境変数が設定されている必要があります。
Gradle は Toolchains 機能により JDK を自動ダウンロードできます。build.gradle
に設定を記述することで、プロジェクトで指定されたバージョンの JDK を Gradle が自動的にダウンロードしてビルドに使用させることが可能です。これにより、開発者間で JDK のバージョンも統一できます。
このように、基本的なソースコードの管理方法は共通化しつつ、ビルドツールの設定や管理方法にそれぞれのツールの特徴が表れています。
プロジェクトのビルドと実行
プロジェクトのビルドは、clean
と install
を組み合わせるのが基本です。これにより、古いビルド成果物を削除し、コードのコンパイル、Checkstyle による静的解析、テストの実行、そして成果物(JAR ファイル)のローカル Maven リポジトリへのインストールが一度に行われます。
# プロジェクトのビルド
./mvnw clean install
初めて実行するときは、必要なパッケージのダウンロードも自動で実行されます。
ビルドが成功すれば、次のコマンドでアプリケーションを実行できます。
# アプリケーションの実行
./mvnw --quiet exec:java -Dexec.mainClass="internal.dev.App"
実行例は次のとおりです。
$ ./mvnw --quiet exec:java -Dexec.mainClass="internal.dev.App"
2025-09-21 23:49:36.480 [internal.dev.App.main()] INFO internal.dev.App - This is an info message.
2025-09-21 23:49:36.487 [internal.dev.App.main()] WARN internal.dev.App - This is a warning message.
2025-09-21 23:49:36.488 [internal.dev.App.main()] ERROR internal.dev.App - This is an error message.
Hello, World from VS Code!
なお、--quiet
オプションは mvnw
コマンド実行時のメッセージを抑制するためのものです。この指定をはずすと、mvnw
の処理についての詳細が表示されます。
実行結果の例は次のようになります。
$ ./mvnw exec:java -Dexec.mainClass="internal.dev.App"
[INFO] Scanning for projects...
(略)
[INFO]
[INFO] --- exec:3.5.1:java (default-cli) @ java-app003 ---
2025-09-21 23:49:36.480 [internal.dev.App.main()] INFO internal.dev.App - This is an info message.
2025-09-21 23:49:36.487 [internal.dev.App.main()] WARN internal.dev.App - This is a warning message.
2025-09-21 23:49:36.488 [internal.dev.App.main()] ERROR internal.dev.App - This is an error message.
Hello, World from VS Code!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.456 s
[INFO] Finished at: 2025-09-22T02:50:34Z
[INFO] ------------------------------------------------------------------------
ドキュメントとテストレポートの生成
pom.xml
には、maven-javadoc-plugin
や maven-surefire-report-plugin
などのレポート生成用プラグインが設定されています。次のコマンドを実行すると、これらのレポートが target/site
ディレクトリにまとめて生成されます。
# Javadoc, テストレポートなどを含むプロジェクトサイトを生成
./mvnw site
生成されたドキュメントをブラウザで確認するには、簡易的な Web サーバーを起動すると便利です。README.md
にも記載されていますが、開発コンテナ内であれば次のように実行します。
# target/site をルートとして Web サーバーを起動
java -m jdk.httpserver -b 0.0.0.0 -p 8000 \
-d /workspaces/dvc-java-gemini/java-app003/target/site
その後、ホストマシンのブラウザで http://localhost:8000 を開きます。プロジェクトの概要、依存関係、ライセンスといった情報に加え、Javadoc (apidocs/index.html
) やテストレポート (surefire-report.html
) へのリンクが設置されたトップページが表示されます。
プロジェクトサイトの画面
VS Code の画面
java-app003.code-workspace
ファイルを使って開いた VS Code のワークスペース画面は次のようになります。
java-app003 ワークスペースの画面
VS Code のプライマリー サイド バーに表示されているエクスプローラーに JAVA PROJECTS
と MAVEN
のビューが追加されている点に注目しましょう。
JAVA PROJECTS
のビューは次のようになります。ビルドツールを指定しないプロジェクトにはない Maven Dependencies
の表示が増えています。
java-app003 ワークスペースの JAVA PROJECTS ビュー
MAVEN
のビューは次のようになります。pom.xml
の内容と大体の対応があることがわかります。
java-app003 ワークスペースの MAVEN ビュー
VS Code でのデバッグ実行
java-app003.code-workspace
ファイルには、VS Code の「実行とデバッグ」機能で利用できる複数の起動構成が定義されています。
起動構成の一覧
最も手軽なのは Debug (Launch) - App です。これを選択してから、デバッグ実行を開始するために緑色の再生ボタン ▶ をクリックします。すると、preLaunchTask
として定義された Build Maven Project
タスク(./mvnw clean install
を実行)が自動的に走り、ビルドが完了した後にデバッグセッションが開始されます。
ソースコードの任意の場所(例えば App.java
の main
メソッド内)にブレークポイントを設定し、このデバッグ構成を実行すれば、そこでプログラムが一時停止し、変数の内容を確認したり、ステップ実行したりできます。
VS Code でのデバッグ実行の様子
デバッグプロファイルを利用したデバッグ実行
このプロジェクトでは、pom.xml
に定義された debug
プロファイルを利用して、アプリケーションをデバッグモードで起動し、そこに VS Code のデバッガを接続(アタッチ)する方法も用意されています。
java-app003.code-workspace
では、このアタッチデバッグのプロセスを完全に自動化する起動構成 Attach to Maven Process with Task が定義されています。
Debug (Launch) - App
の方は VS Code の機能を利用するものなので手軽に使えますが、カスタマイズする場合は Maven と組み合わせるようにした方が、開発の全体効率が上がります。Maven のプロファイルを利用するデバッグ実行の設定方法を知っておくと、VS Code でもテーミナルのコマンドでも、どちらでもデバッグ実行ができるようになります。
起動構成について実際のコードは java-app003.code-workspace
の launch
にあります。ここでは処理の概要について説明することにして、コードについては後で説明します。
Attach to Maven Process with Task
を実行するには、「実行とデバッグ」ビューでこれを選択し、デバッグを開始(緑色の再生ボタン ▶ をクリック)するだけです。
初めて実行したときは、problemMatcher
についての警告画面が表示されますが、「このタスクの選択内容を保存」をチェックし、「このままデバッグ」をクリックして進めます。
なお、この起動構成では、以下の処理がすべて自動的に実行されます。
-
preLaunchTask
の実行 - デバッガのアタッチ
- デバッグセッションの開始
-
postDebugTask
の実行
最初に preLaunchTask
に指定されたタスクが実行されます。ここでは、App.java の Java プログラムがデバッグ待機状態(ポート 5005 番)で起動します。
次に、デバッガのアタッチが実行になります。VS Code の Java デバッガが、起動したプロセスのポート 5005 番に自動的に接続します。
アタッチが成功すると、デバッグセッションが開始されます。デバッグセッション内で、ブレークポイントを追加設定したり、ステップ実行したりできるようになります。
プログラムを終了すると、デバッグセッションが終了となります。このとき、postDebugTask
が自動実行されます。ここでは、バックグラウンドで実行されていた Maven プロセスが自動的に終了し、ポートが解放されます。
この構成のおかげで、開発者はターミナルで手動でコマンドを実行したり、プロセスを停止したりする手間から解放され、VS Code の UI 操作だけでアタッチデバッグの開始から終了までを完結させることができます。
ただし、ここで採用している設定方法では、「デバッガの切断」と「デバッガの停止」が同じ動作となってしまいます。どちらも、デバッグモードで起動してあるプログラムを自動停止してしまいます。
使用技術の解説
ここでは、java-app003
で利用されている主要な技術や設定について、初心者向けに解説します。
Maven と pom.xml
Maven プロジェクトの中心となるのが、プロジェクトオブジェクトモデル (POM) を定義する pom.xml
ファイルです。先に解説した Maven の概念(ライフサイクル、依存関係管理など)は、すべてこのファイル内の記述に基づいて機能します。
Maven は「設定より規約 (Convention over Configuration)」という設計思想を重視しており、「Java のソースコードは src/main/java
に置く」といった規約に従うことで、pom.xml
の記述を最小限に抑えられます。
このセクションでは、java-app003
の pom.xml
を例に、その具体的な構造と設定内容を解説します。
pom.xml
の主な要素
java-app003
の pom.xml
を例に、主要な要素を見ていきましょう。これは、大きく次の要素から構成されています。
- プロジェクト情報
- プロパティ
- 依存ライブラリ
- ビルド設定
- レポート設定
- プロファイル
それぞれについて説明します。
プロジェクト情報としては、<groupId>
, <artifactId>
, <version>
, <packaging>
といったものがあります。これらは、プロジェクトを一意に識別するための情報です。groupId
は組織やグループ、artifactId
は成果物(ライブラリやアプリケーション)の名前、version
はそのバージョン、packaging
はパッケージのフォーマットを表します。パッケージのフォーマットには、アプリケーションやライブラリなら jar
、Web アプリケーションなら war
を指定します。
<groupId>internal.dev</groupId>
<artifactId>java-app003</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
プロパティは <properties>
に指定します。これはプロジェクト全体で利用する設定値を定義します。例えば、Java のバージョンや、他の場所で参照する値をまとめておくのに便利です。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
依存ライブラリは <dependencies>
に指定します。ここにはプロジェクトが必要とする外部のライブラリを記述します。ここに記述されたライブラリは、Maven が自動的にダウンロードしてクラスパスに追加してくれます。
<!-- 略 -->
<!-- SLF4J API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.13</version>
</dependency>
<!-- Logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.6</version>
</dependency>
<!-- 略 -->
ビルド設定は <build>
に指定します。ここには、プロジェクトのビルド方法を定義します。特に重要なのが <plugins>
で、コンパイル、テスト、パッケージングといった各工程で実行される Maven プラグインを設定します。
-
maven-compiler-plugin
: Java ソースコードをコンパイル -
maven-surefire-plugin
: ユニットテストを実行 -
maven-checkstyle-plugin
: コードスタイルをチェック -
exec-maven-plugin
: アプリケーションを実行
レポート設定は <reporting>
に指定します。ここには、./mvnw site
コマンドで生成されるプロジェクトサイトに含めるレポートの種類を設定します。maven-javadoc-plugin
や maven-surefire-report-plugin
をここに設定することで、Javadoc やテストレポートがサイトに含まれるようになります。
プロファイルは <profiles>
に指定します。プロファイルというのは、特定の状況に応じてビルド設定を切り替えるための仕組みです。これについては後述します。
VS Code と Maven の連携
VS Code は、「Extension Pack for Java」に含まれる「Maven for Java」拡張機能によって、Maven プロジェクトを強力にサポートします。
Maven ビュー
VS Code のサイドバーには「MAVEN」という専用のビューが表示されます。ここには、現在のプロジェクト(java-app003
)がツリー形式で表示され、GUI で操作を行うことができます。
Lifecycle
Plugins
Dependencies
Lifecycle
には clean
, validate
, compile
, install
といった Maven の主要なビルドライフサイクル・フェーズが一覧表示されます。
Plugins
には、プロジェクトで利用しているプラグインとそのゴール(プラグインが提供する個別の機能)が一覧表示されます。ここから特定のゴールだけを実行することも可能です。
Dependencies
には、プロジェクトの依存ライブラリが一覧表示されます。ライブラリのバージョン競合などを確認するのに役立ちます。
MAVEN ビューの画面は一度見ていますが、改めて、ここでも示しておきます。Lifecycle
にある各項目の横にある再生ボタン ▶ を押すと、そのフェーズのビルドが実行されます。
MAVEN ビュー
MAVEN ビューではプロファイルの有効化もできます。有効化したいプロファイルにマウスを合わせると、右側に +
マークが表示されるので、クリックします。すると、+
マークが -
マークに変わり、プロファイルの先頭にチェックマーク(✔)がつきます。
MAVEN ビューでの debug プロファイル有効化
プロファイルの無効化をするには、無効化したいプロファイルにマウスを合わせると、右側に表示される-
マークをクリックします。
java-app003.code-workspace
)
ワークスペース設定 (java-app003.code-workspace
ファイルは、このプロジェクトを VS Code で開いたときに適用される設定をまとめたものです。これにより、開発者ごとに環境設定がバラバラになるのを防ぎます。
Maven 関連の設定:
settings
の中には、Maven 開発を快適にするための設定が含まれています。
"settings": {
// ...
"maven.terminal.useJavaHome": true,
"java.jdt.ls.java.home": "/usr/local/sdkman/candidates/java/21.0.7-tem",
// ...
"maven.view": "hierarchical",
"java.configuration.updateBuildConfiguration": "interactive",
"java.debug.settings.jdwp.requestTimeout": 15000
}
設定項目 | 説明 |
---|---|
java.jdt.ls.java.home |
VS Code 用の Java Language Server が使用する JDK を設定します。 |
maven.terminal.useJavaHome |
Maven 用のターミナルが使用する JDK を設定します。 |
maven.view |
Maven ビューの表示形式を hierarchical (階層表示)に設定します。 |
java.configuration.updateBuildConfiguration |
ビルド構成ファイル(pom.xml など)が変更された際のプロジェクト構成の更新方法を制御します。 |
java.debug.settings.jdwp.requestTimeout |
デバッガがターゲット JVM と通信する際の JDWP リクエストのタイムアウト時間(ms)を設定します。 |
java.configuration.updateBuildConfiguration
については、interactive
を指定すると、変更を検知した際に更新するかどうかをユーザーに問い合わせるプロンプトが表示されます。"automatic"
を指定すると、ユーザーの許可なしに自動で更新されるようになります。
java.debug.settings.jdwp.requestTimeout
については、短いと後で説明するタスクの Attach to Maven Process with Task
を利用する時に問題が起きることがあります。
launch
と tasks
の詳細
VS Code のデバッグ機能を最大限に活用するため、launch
(起動構成)と tasks
(タスク定義)を連携させています。tasks
にビルドや外部コマンドの実行といった具体的な処理を定義し、launch
からそれらを呼び出すことで、複雑なデバッグフローを自動化できます。
java-app003.code-workspace
に定義されている主要な launch
と tasks
の設定を、コードと共に見ていきましょう。
tasks
の設定
tasks
セクションには、デバッグの前後やビルドで実行したいシェルコマンドなどを定義します。ここでは次のタスクについて説明します。
Build Maven Project
Run Maven with Debug
Stop Maven Debug Process
Build Maven Project:
Build Maven Project
は、プロジェクトをビルドするためのタスクです。Debug (Launch) - App
起動構成の preLaunchTask
から呼び出されます。
{
"label": "Build Maven Project",
"type": "shell",
"command": "./mvnw clean install",
"problemMatcher": ["$msCompile"],
"group": {
"kind": "build",
"isDefault": true
}
}
各設定項目の説明を表にしました。
設定項目 | 説明 |
---|---|
label |
タスクを識別するための名前。 |
type |
タスクの種類。 |
command |
実行するコマンド。 |
problemMatcher |
コマンドの出力からエラーや警告を検出し、VS Code の「問題」パネルに表示するためのパターン。 |
group |
タスクをグループ化するための設定。 |
label
に指定したラベル文字列を使って、launch
構成からタスクを参照することができます。
type
に shell
を指定すると、シェルコマンドを実行できます。
ここでは command
に Maven Wrapper を指定して、ビルドを実行しています。
problemMatcher
の指定にある $msCompile
は、一般的なコンパイラの出力形式に対応する定義済みパターンです。
ここでは group
に kind: "build"
と isDefault: true
を設定し、このタスクがデフォルトのビルドタスクとなるようにしています。
Run Maven with Debug:
次に用意してある Run Maven with Debug
は、アタッチデバッグ用に、アプリケーションをデバッグモードで起動するタスクです。isBackground: true
になっているため、このタスクはバックグラウンドで実行され続け、他の処理をブロックしません。
{
"label": "Run Maven with Debug",
"type": "shell",
"command": "./mvnw",
"args": ["exec:exec", "-Pdebug"],
"problemMatcher": [],
"isBackground": true
}
まだ説明していない設定項目のみ表にしました。
設定項目 | 説明 |
---|---|
args |
コマンドに渡す引数の配列。 |
isBackground |
バックグランド実行をするときに指定 |
ここでは args
に exec:exec
ゴールと debug
プロファイルを指定しています。
isBackground
に true
に設定すると、このタスクはバックグラウンドで実行され、終了を待ちません。デバッグサーバーのように、長時間実行されるプロセスを起動する場合に利用します。
Stop Maven Debug Process:
Stop Maven Debug Process
は、アタッチデバッグ終了後に、起動していたデバッグプロセスを停止するための後処理タスクです。ポート 5005
を使用しているプロセスを探して終了させます。
{
"label": "Stop Maven Debug Process",
"type": "shell",
"command": "ss -tln | grep :5005 > /dev/null && fuser -k 5005/tcp || true",
"problemMatcher": []
}
ここの command
の指定にあるコマンドは、ポート 5005 を使用しているプロセスを検索して終了させます。ポートが未使用の場合でもエラーにならないように、最後に || true
を付けています。
なお、ここではタスクのコマンド実行時の出力を解析する必要がないため、problemMatcher
の指定を空の配列 []
としていす。
launch
の設定
launch
セクションでは、デバッグのシナリオごとに異なる起動構成を定義します。ここでは、このプロジェクトでよく使う次の 2 つについて説明します。
Debug (Launch) - App
Attach to Maven Process with Task
Debug (Launch) - App:
Debug (Launch) - App
は、アプリケーションを直接起動してデバッグする、最もシンプルな構成です。
{
"type": "java",
"name": "Debug (Launch) - App",
"request": "launch",
"mainClass": "internal.dev.App",
"projectName": "java-app003",
"preLaunchTask": "Build Maven Project"
}
各設定項目の説明は次の表にあるとおりです。
設定項目 | 説明 |
---|---|
type |
デバッガの種類 |
name |
起動構成の名前 |
request |
デバッグセッションの種類 |
mainClass |
実行するメインクラスの完全修飾名 |
projectName |
対象となる Java プロジェクトの名前 |
preLaunchTask |
デバッグセッションを開始する前に実行するタスク |
Java のデバッガを使用するため、type
には java
と指定します。
name
に指定した値は、「実行とデバッグ」ビューに表示されます。
request
に launch
を指定すると、新しいプロセスを起動してデバッグすることになります。
mainClass
には、今回使用するメインクラスの internal.dev.App
を指定します。
projectName
には、プロジェクト名 java-app003
を指定します。
preLaunchTask
には tasks
で用意したタスクをラベル(label
)で指定します。ここでは、tasks
で定義した Build Maven Project
を指定し、デバッグ開始前に必ずビルドが実行されるようにしています。
Attach to Maven Process with Task:
Attach to Maven Process with Task
は、アタッチデバッグの全工程を自動化する構成です。
この設定で、デバッグプロセスの起動から、デバッガをアタッチし、デバッグプロセスを停止するまでの一連の流れをワンクリックで実行できるようになります。
{
"type": "java",
"name": "Attach to Maven Process with Task",
"request": "attach",
"hostName": "localhost",
"port": 5005,
"preLaunchTask": "Run Maven with Debug",
"postDebugTask": "Stop Maven Debug Process",
"projectName": "java-app003"
}
まだ説明していない設定項目についてのみ表にしました。
設定項目 | 説明 |
---|---|
hostName |
アタッチするプロセスが実行されているホスト名 |
port |
アタッチするプロセスがデバッグ接続を待ち受けているポート番号 |
preLaunchTask |
デバッグセッションを開始する前に実行するタスク |
postDebugTask |
デバッグセッションが終了した後に実行するタスク |
request
に attach
を指定すると、すでに実行中のプロセスにデバッガを接続(アタッチ)することになります。
ここでは hostName
には、localhost
を指定して、同じマシン上で実行されているプロセスにアタッチするようにしています。
また、preLaunchTask
には、デバッグモードで Maven プロセスを起動する Run Maven with Debug
を指定します。
postDebugTask
には、バックグラウンドで実行されている Maven プロセスを停止する Stop Maven Debug Process
を指定しています。
このように launch
と tasks
を連携させることで、VS Code のデバッグ実行ボタン一つで、ビルドからデバッグ、後処理までを完結させることができます。
Javadoc とは
Javadoc とは、Java のソースコード内に特定の形式で記述されたコメントから、API 仕様書を HTML 形式で生成するためのツールです。/** ... */
という形式のコメントブロック内に、@param
(引数) や @return
(戻り値) といったタグを使ってクラスやメソッドの仕様を記述します。詳しくは、Oracle が提供する公式ドキュメントを参照してください。
この仕組みに従ってコードにドキュメントを埋め込んでおくことで、コードそのものがドキュメントとして機能し、いつでも最新の API 仕様書を生成できるようになります。
次に Javadoc 用のコメントを書いたプログラムの例を示します。
package internal.dev;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The main application class.
*/
public class App {
/**
* Prevents instantiation of this utility class.
*/
private App() {
}
/** The logger. */
private static final Logger logger = LoggerFactory.getLogger(App.class);
/**
* Returns a greeting message and logs some messages.
*
* @return The greeting "Hello, World from VS Code!"
*/
public static String getGreeting() {
logger.info("This is an info message.");
logger.warn("This is a warning message.");
logger.error("This is an error message.");
return "Hello, World from VS Code!";
}
/**
* The main entry point of the program.
*
* @param args The command line arguments (not used).
* @throws Exception If an exception occurs.
*/
public static void main(String[] args) throws Exception {
System.out.println(getGreeting());
}
}
上記のようなコメントを書いておくと、Javadoc はクラスやメソッドの説明、引数(@param
)、戻り値(@return
)といった情報を解析し、見やすいドキュメントを生成してくれます。
Maven では、maven-javadoc-plugin
を使えば Javadoc のドキュメント生成に対応できます。java-app003
では、このプラグインを設定し、./mvnw site
コマンドで Javadoc を生成できるようにしています。
mvnw site
の連携の仕組み
Javadoc と ./mvnw site
コマンドを実行したときに Javadoc が生成されるのは、pom.xml
の <reporting>
セクションに maven-javadoc-plugin
が設定されているためです。
Maven には、compile
や test
, package
といったビルドの各工程を定義した「ライフサイクル」という概念があります。site
もそのライフサイクルの一つで、プロジェクトに関する情報やレポートをまとめた Web サイトを生成する役割を担います。
./mvnw site
コマンドを実行すると、Maven は site
ライフサイクルを実行します。その際、pom.xml
の <reporting>
セクションに記述されたプラグインを呼び出し、レポートを生成させます。
java-app003
の pom.xml
では、<reporting>
セクションに maven-javadoc-plugin
や maven-surefire-report-plugin
が含まれているため、./mvnw site
を実行するだけで、Javadoc やテストレポートが自動的に生成され、プロジェクトサイトに統合されるのです。
Maven Surefire Report Plugin とは
Maven Surefire Report Plugin は、ユニットテストの結果をまとめたレポートを HTML 形式で生成するためのプラグインです。
Maven でテストを実行する際、実際には maven-surefire-plugin
という別のプラグインが使われます。このプラグインが JUnit などのテストフレームワークを呼び出してテストを実行し、結果を XML ファイルに出力します。
Surefire Report Plugin は、その XML ファイルを読み込んで、人間が見やすい形の HTML レポートを生成する役割を担います。./mvnw site
を実行すると、このプラグインが動作し、target/site/surefire-report.html
というファイルが作成されます。このレポートを見れば、どのテストが成功し、どれが失敗したのかが一目でわかります。
Maven プロファイル とは
Maven プロファイルは、特定の状況に応じてビルド設定を切り替えるための仕組みです。例えば、「開発中はこの設定、本番環境向けにビルドするときは別の設定」といった使い分けができます。
プロファイルは pom.xml
内の <profiles>
タグで定義し、それぞれに ID を付けます。そして、コマンドラインで -P
オプションを使って有効にするプロファイルを指定します。
java-app003
の pom.xml
には debug
という ID のプロファイルが定義されています。
<profiles>
<profile>
<id>debug</id>
<properties>
<exec.jvmargs>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005</exec.jvmargs>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<classpath />
<argument>${exec.jvmargs}</argument>
<argument>internal.dev.App</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
このプロファイルは、有効になったときに特定のビルド設定を適用します。
-
<properties>
:exec.jvmargs
というプロパティを定義し、JVM をデバッグモードで起動するための引数を設定します。 -
<build>
:exec-maven-plugin
を設定し、アプリケーションを起動できるようにします。
ここで設定したゴールを利用するには、mvnw
実行時に debug
プロファイルを有効にする必要があります。
./mvnw exec:exec -Pdebug
のように -Pdebug
を付けて実行すると debug
プロファイルが有効になります。これにより、<build>
内の exec-maven-plugin
が利用可能になり、かつ <properties>
で定義されたデバッグ用の JVM 引数 (-agentlib:jdwp=...
) が ${exec.jvmargs}
に渡されます。結果として、アプリケーションがデバッグモードで起動する、という仕組みです。
まとめ
本記事では、開発コンテナ環境で Apache Maven プロジェクトを開発する方法について、具体的なサンプル java-app003
を通して解説しました。
Maven の中心的な概念である POM (pom.xml
)、ビルドライフサイクル、依存関係管理の仕組みを理解することで、プロジェクトのビルド、テスト、ドキュメント生成といった一連のプロセスを自動化し、効率化できることを示しました。
また、VS Code の拡張機能やワークスペース設定を活用することで、Maven プロジェクトのデバッグ実行が容易になることも確認しました。特に、launch
と tasks
を連携させたデバッグ構成や、デバッグ用のプロファイルを使ったアタッチデバッグは、実践的な開発で役立つでしょう。
この記事で紹介した pom.xml
の設定や各種プラグイン(Checkstyle, Javadoc, Surefire Report など)は、多くの Java プロジェクトで応用できるものです。本記事が、皆さんの Maven を使った Java 開発の一助となれば幸いです。
Discussion