【入門編】Maven/Gradleで「隠れた依存関係」を暴く!未使用ライブラリによるプロジェクト肥大化を撃退する – ビルド・パッケージ管理ツール生産性向上バイブル

こんにちは!日々の開発、本当にお疲れ様です。Javaのプロジェクトを進めていると、なんだか最近ビルドが遅くなってきたな……とか、Dockerコンテナに固めた成果物のサイズがやけに膨らんでいるな……と感じたことはありませんか?

その原因、もしかすると「誰も使っていない、隠れたゾンビ依存関係」にあるかもしれません。

今回は、MavenやGradleというビルドツールを使いこなし、プロジェクトに巣食う使われていないライブラリをキレイさっぱり駆逐する方法を解説します。これをマスターすれば、毎日のコーディングやCI/CDの待ち時間が劇的に短縮され、軽やかな開発環境を手に入れることができますよ。さあ、一緒に紐解いていきましょう!

—

1. なぜ「隠れた依存関係」がプロジェクトを蝕むのか?

Javaの開発では、Mavenの `pom.xml` や Gradleの `build.gradle` にライブラリ(依存関係)を記述しますよね。ここで気をつけたいのが「推移的依存関係(Transitive Dependencies)」です。

例えば、あなたが「Aという便利なライブラリ」を1つ追加したとします。しかし、その裏でAが依存している「B」「C」「D」というライブラリまで、自動的にプロジェクトへ取り込まれてしまいます。
これが何層にも重なると、「自分が直接書いていないけれど、なぜかclasspathに含まれている巨大なライブラリの山」が完成します。

この状態を放置すると、以下のような恐ろしいペナルティを支払うことになります。

  • ビルド時間の肥大化: コンパイラが不要なクラスファイルを走査するため、無駄にCPUと時間が奪われます。
  • 配布サイズの増大: マイクロサービスやサーバーレス環境(AWS Lambdaなど)において、デプロイパッケージが重くなり、デプロイや起動速度に悪影響を与えます。
  • セキュリティリスク(脆弱性の温床): 使ってもいない古いライブラリに致命的な脆弱性が見つかり、アラート対応に追われるという不毛な事態を招きます。

これを根本から解決するのが、今回紹介する依存関係の解析ツールです。

—

2. ツール選定と環境の基礎セットアップ

まずは、MavenとGradle、それぞれの環境で「隠れた依存関係」を暴くための武器を準備しましょう。特別なインストールの必要はなく、すでに手元にあるビルドツールの標準機能やプラグインを呼び出すだけです。

Mavenの場合:`maven-dependency-plugin`

Mavenには標準で強力な解析ゴールが備わっています。特別な設定は不要ですが、確実に動作させるために `pom.xml` の `` セクションにプラグインバージョンを明記しておくと安全です。

org.apache.maven.plugins
maven-dependency-plugin
3.6.1

Gradleの場合:標準タスク & Dependency Insight

Gradleは、プロジェクトの依存関係グラフを美しく解析する機能が最初から組み込まれています。特別なプラグイン追加は不要ですが、より詳細なインサイトを得るために、最新のGradleラッパー(7.x以降)を使用していることを確認してください。

—

3. 実践!「使われていない依存関係」を暴き出すコマンド

それでは、実際にプロジェクトをスキャンしてみましょう。ここからが腕の見せどころです。

Mavenで未使用ライブラリを炙り出す

プロジェクトのルートディレクトリ(`pom.xml` がある場所)で、以下のコマンドを実行します。

バイトコードレベルで実際のソースコードの使用状況と依存関係を突合する
mvn dependency:analyze

実行すると、ビルドログの中に以下のようなセクションが出現します。ここが宝の山です!

[INFO] — maven-dependency-plugin:3.6.1:analyze (default-cli) @ my-app —
[INFO] Used declared dependencies:
[INFO] org.springframework.boot:spring-boot-starter-web:jar:3.1.0:compile
[INFO] Unused declared dependencies:
[INFO] commons-io:commons-io:jar:2.11.0:compile <-- ★ここ!宣言したけど使われていない [INFO] Used undeclared dependencies: [INFO] org.slf4j:slf4j-api:jar:2.0.7:compile <-- 隠れんぼしている依存関係

  • Unused declared dependencies: 「pom.xmlに書いたけど、コード内で一度もインポートされていない(=消していい子)」
  • Used undeclared dependencies: 「pom.xmlに書いてないのに、なぜかコード内で使われている(=推移的依存関係に頼りきっていて危険な子)」

Gradleで依存関係の深層を暴く

Gradleの場合は、特定の依存関係が「なぜ・どこから持ち込まれたのか」を追跡する `dependencyInsight` タスクが非常に強力です。

例えば、gsonというライブラリがどこから迷い込んだのかを完全に追跡する
./gradlew dependencyInsight –dependency gson

出力例:

com.google.code.gson:gson:2.8.9
variant “compile” [
…
]
Selection reasons:

  • JFrog Artifactoryなどから自動解決されたバージョン

Depends on:

  • com.example:my-library:1.0.0 (my-libraryがgsonを内部で使っているため混入)

さらに、プロジェクト全体の未使用依存関係を網羅的にチェックしたい場合は、オープンソースの [Gradle Dependency Analyzer (com.autonomouslogic.dependency-analysis)](https://github.com/autonomouslogic/dependency-analysis) プラグインを導入するのがベストプラクティスです。

`build.gradle` に以下を追加します:

plugins {
// 依存関係の肥大化を検知するプラグインを適用
id “com.autonomouslogic.dependency-analysis” version “1.28.0”
}

// タスクを実行すると、プロジェクトの依存関係レポートがbuild/reportsに生成されます

ターミナルで以下を叩きます。

./gradlew buildHealth

これで、どの依存関係を削除すべきかが一目でわかるレポートが生成されます。

—

4. 成果を測定する:ビルド時間と配布サイズの削減効果

「本当にこれを消して意味があるの?」と思うかもしれませんが、実際の数値として成果を測定してみましょう。

1. 配布サイズ(JAR / WAR / Dockerイメージ)の測定

依存関係を削除する前後で、ビルド成果物の重さを比較します。

ビルド成果物(例: target/ または build/libs/)のファイルサイズを確認
ls -lh build/libs/my-app-0.0.1-SNAPSHOT.jar

  • 改善前: 45 MB (使っていない重いライブラリやその依存関係が含まれている)
  • 改善後: 18 MB (なんと約60%の軽量化!)

このサイズ削減は、KubernetesのPod起動時におけるコンテナイメージのpull時間を劇的に短縮し、クラウドのストレージ・転送コスト削減にも直結します。

2. クリーンビルド時間の測定

Javaのコンパイラ(javac)やIDEは、クラスパスに含まれるJARファイルが多いほど、シンボル解決に時間がかかります。

クリーンな状態からビルド時間を計測する
time ./gradlew clean build -x test

  • 改善前: 1分 45秒
  • 改善後: 55秒 (約2倍の高速化!)

毎回のローカルビルドや、CI/CDパイプライン(GitHub ActionsやGitLab CIなど)での待ち時間が半分になることで、開発者の「思考の分断」を防ぎ、フロー状態を維持しやすくなります。

—

5. 現場で安全にゾンビ依存を削除するための注意点

最後に、アーキテクトからの重要なアドバイスです。解析ツールが「Unused(未使用)」と判定したからといって、即座に `pom.xml` や `build.gradle` から消し去るのは少し待ってください。

以下のケースでは、静的解析ツールが検知しきれないことがあります。
1. リフレクション(Reflection)や動的ロード: コード内で直接 `import` していないが、文字列名でクラスを動的ロードしている場合(例: JDBCドライバ、一部のDIフレームワークのプラグインなど)。
2. ロギングの実装依存: `SLF4J` の APIだけコードに書いておき、実際のログ出力実装(`Logback` など)は設定や推移的依存関係に任せている場合。

安全な進め方:
1. まず解析ツールで「Unused」と出たものをコメントアウト、または削除する。
2. アプリケーションをビルドし、すべての単体テスト(Unit Test)および結合テスト(Integration Test)を必ず実行する。
3. ローカル環境で実際にアプリケーションを起動し、主要なエンドポイントが正常に動作するかスモークテストを行う。

この手順を踏めば、誤って動的依存関係を壊してしまうリスクを完全にゼロにできます。

—

まとめ

今回は、MavenやGradleを駆使して「隠れた依存関係」を暴き出し、プロジェクトの軽量化とビルド高速化を実現する方法を解説しました。

  • Mavenなら `mvn dependency:analyze`
  • Gradleなら `dependencyInsight` や専用プラグイン

を使いこなすことで、あなたのプロジェクトは見違えるほど軽やかになります。
「動けばいいや」と放置された無数のライブラリを整理整頓することは、コードの美しさを保つだけでなく、セキュリティを高め、チーム全体の開発体験(DX)を最高のものへと引き上げます。

ぜひ、今日の業務からあなたのプロジェクトでも試してみてください。毎日のコーディングが驚くほど軽快になりますよ!

タイトルとURLをコピーしました