44

多くの依存関係を持つ Maven プロジェクトをビルドする場合、それらの依存関係の一部は同じライブラリに依存していますが、アプリケーションの実行時にエラーを引き起こしている別のバージョンを使用しています。

たとえば、2 つの異なるプロジェクト依存関係 (A と B) を追加した場合、両方とも Apache Commons HTTP クライアントに依存しているが、それぞれが異なるバージョンに依存している場合、クラスローダーが A の Apache commons http クライアント クラスをロードすると、B はそれらを使用しようとします。これらは、クラス・ローダーによってすでにロードされています。

しかし、B のバイトコードはロードされたクラスの異なるバージョンに依存しており、アプリケーションの実行時に複数の問題を引き起こしています。よくある例外は、メソッドが見つからないという例外です (A のバージョンの HTTP クライアントは特定のメソッドを使用しなくなったため)。

このような競合を回避するために構築するときの一般的な戦略は何ですか? 依存関係ツリーを手動でチェックして、どの共通ライブラリが互いに衝突するかを把握する必要がありますか?

4

4 に答える 4

28

親しみを込めて知られているように、Maven依存地獄へようこそ。これは、プロジェクトが成長し、より多くの外部依存関係が導入されるにつれて、いくぶん一般的な問題です。

Apache Commons (元の質問で言及) に加えて、ロギング フレームワーク (log4j、slf4j) もよくある原因です。

競合が特定された後の解決方法について、「matts」のアドバイスに同意します。これらのバージョンの競合を早期に発見するという点では、maven の「enforcer」プラグインを使用することもできます。「dependencyConvergence」構成を参照してください。このSO投稿も参照してください。

エンフォーサ プラグインを使用すると、バージョンの競合が発生するとすぐにビルドが失敗するため、手動でチェックする必要がなくなります。これは積極的な戦略ですが、質問/投稿の原因となったタイプの実行時の問題を防ぎます。何でもそうですが、エンフォーサ プラグインには長所と短所があります。昨年中に使い始めましたが、それが祝福と呪いになる可能性があることを発見しました. libs/frameworks の多くのバージョンは下位互換性があるため、(直接的または間接的に) バージョン 1.2.3 と 1.2.4 の両方に依存しても、コンパイル時と実行時の両方で問題ないことがよくあります。ただし、エンフォーサー プラグインはこの競合にフラグを立て、必要なバージョンを正確に宣言する必要があります。依存関係の競合の数が少ないと仮定すると、これには多くの作業は必要ありません。ただし、大規模なフレームワーク (Spring MVC など) を導入すると、厄介な問題が発生する可能性があります。

うまくいけば、それは有用な情報です。

于 2013-10-31T06:45:24.853 に答える