Mavenキャッシュ(.m2)が原因で起きるトラブル集

Mavenでのビルドトラブルのうち、意外と多いのが「コードは何も変えていないのに、なぜか動かない」「別の人の環境では通るのに、自分だけ失敗する」といった現象です。その原因としてかなりの割合を占めるのが、ローカルに保存されているMavenキャッシュ、いわゆる .m2 ディレクトリです。

先に結論めいたことを言ってしまうと、Mavenの .m2 キャッシュは便利な反面、壊れる・古くなる・意図せず使われ続けるという性質があり、トラブルが起きたときに「疑うべきポイント」になりやすい存在です。ただし、やみくもに削除すればいいわけでもなく、状況を見誤ると別の問題を引き起こすこともあります。

この記事では、Mavenキャッシュ(.m2)が原因で起きがちなトラブルを具体例ベースで整理しつつ、実際の現場でどう対処するのが無難かを掘り下げていきます。

Mavenキャッシュ(.m2)とは何をしているのか

Mavenを使っていると、ホームディレクトリ配下に .m2/repository というディレクトリが作られます。ここには、過去にダウンロードした依存ライブラリのjarやpomが保存されています。

毎回リモートリポジトリから取得すると時間も通信量もかかるため、一度取得した成果物をローカルにキャッシュする、というのが本来の役割です。この仕組み自体は非常に合理的ですが、「ローカルに状態が残る」という点がトラブルの温床にもなります。

Mavenキャッシュが原因で起きがちな代表的トラブル

ビルドが突然失敗するようになった

昨日まで通っていた mvn clean install が、急に失敗するケースです。エラーメッセージを見ると、依存ライブラリのクラスが見つからない、あるいはjarが壊れているような内容が出ることがあります。

この場合、.m2 内に保存されているjarが不完全な状態でダウンロードされていたり、途中で壊れてしまっている可能性があります。ネットワークが不安定な状態で初回ダウンロードが走ったときなどに、まれに起きます。

表面的にはコードの問題に見えますが、実際にはローカルキャッシュを消して再取得すると、あっさり解決することも少なくありません。

依存関係を更新したはずなのに反映されない

pom.xml を修正してバージョンを上げたのに、動作が変わらない、ログを見ると古いライブラリが使われているように見える、というケースも典型的です。

これは、SNAPSHOT依存や、同一バージョンで中身だけ変わった成果物を使っている場合に起きやすいです。Mavenは基本的に「同じバージョン番号の成果物は同じもの」とみなすため、ローカルキャッシュが優先されてしまいます。

この挙動を理解していないと、「デプロイしたのに反映されない」「CIでは直っているのにローカルではおかしい」といった混乱につながります。

他の人の環境では通るのに自分だけ失敗する

チーム開発で非常によくあるパターンです。Gitで同じコードをチェックアウトしているのに、Aさんの環境では成功し、Bさんの環境では失敗する。

この場合、pom.xml や設定ファイルよりも、.m2 に溜まった依存関係の差異を疑う価値があります。過去に使っていた古いライブラリが残っていたり、ローカルでしか存在しないアーティファクトが影響していることがあります。

Mavenのエラーメッセージがやたら分かりにくい

「Could not resolve dependencies」や「Failed to read artifact descriptor」といったエラーが出たとき、原因がネットワークなのか、リポジトリなのか、キャッシュなのか判断しづらいことがあります。

この種のエラーは、実は .m2 内のメタデータ(_maven.repositories や .lastUpdated ファイル)が原因であることもあります。一度失敗した情報がキャッシュされ、それを元にMavenが「もう無理」と判断し続けてしまうケースです。

よくある「.m2削除すればOK」思考の落とし穴

トラブルシューティングの記事やQ&Aを見ると、「.m2 を削除してください」という回答がよく出てきます。確かに即効性がある場合も多いですが、常に正解とは限りません。

無差別削除による時間ロス

.m2 を丸ごと削除すると、次回ビルド時にすべての依存関係を再ダウンロードすることになります。プロジェクトが大きい場合、かなりの時間がかかりますし、社内リポジトリやVPN環境だと失敗するリスクも高まります。

根本原因を見失う

キャッシュを消したら直った、という体験が続くと、「なぜ壊れたのか」「どういう条件で再発するのか」を考えなくなりがちです。結果として、同じトラブルを何度も繰り返すことになります。

CIや本番では再現しない問題を作る可能性

ローカルだけで .m2 を消して直った状態が、CI環境や別マシンでは再現しないこともあります。この場合、実は設定ミスや依存定義の曖昧さが隠れている可能性があります。

実務でよく使われる現実的な対処パターン

特定ライブラリだけ削除する

まず試したいのは、問題がありそうなライブラリ配下だけを削除する方法です。たとえば groupId 単位でディレクトリを消します。

rm -rf ~/.m2/repository/com/example/problematic-lib

これで影響範囲を最小限に抑えつつ、再取得を促せます。

-U オプションを使って強制更新する

Mavenには、リモートリポジトリを強制的にチェックするオプションがあります。

mvn clean install -U

SNAPSHOT依存や、キャッシュが怪しいときには、まずこれを試すのが無難です。

.lastUpdated ファイルを削除する

依存解決に失敗した際に作られる .lastUpdated ファイルが原因で、以後ずっと失敗し続けることがあります。このファイルだけを削除すると、再チャレンジしてくれる場合があります。

Mavenキャッシュ絡みのトラブルを減らすための考え方

完全にトラブルをゼロにするのは難しいですが、意識するだけで減らせるポイントはあります。

  • SNAPSHOT依存を多用しすぎない
  • 同一バージョンで中身を変える運用を避ける
  • 社内リポジトリの安定性を保つ
  • 「困ったら即 .m2 全削除」を癖にしない

これらは地味ですが、積み重ねるとチーム全体のトラブル対応コストが下がります。

結局どうすればいいか

Mavenキャッシュ(.m2)は、ビルドを高速化してくれる重要な仕組みですが、状態を持つがゆえにトラブルの原因にもなりやすい存在です。

何かおかしいと感じたときは、コードや設定だけでなく、「ローカルキャッシュに何が残っているか」を一度疑ってみるのが現実的です。ただし、無条件に全部消すのではなく、影響範囲を意識しながら段階的に対処するのが、安全で再現性のあるやり方と言えます。

Mavenの .m2 は敵ではありませんが、放置すると厄介者になります。仕組みを理解したうえで、上手に付き合っていくことが、長くJava開発を続けるコツです。