2012-01-18 1 views
3

プロジェクトAの依存関係(過渡的な依存関係を含む)を例として考えてみましょう。依存ツリーを見ると、1つのパスの最後にはslf4j-api:1.6.4があり、別のパスの最後にはslf4j:1.6.1があります。競合する依存関係:どのように選択するのですか?

どの依存関係を選択する必要がありますか? slf4j:1.6.4を選択した場合、クラスパスにバージョン1.6.1がなく、バージョン1.6.4がバージョン1.6.1を使用するコードと互換性があるかどうかをどのように知ることができますか?

最後に私のクラスパスには1つのslf4jバージョンしかないのでわかりません。

おかげ

答えて

1

これは、C/C++で "DLL地獄" に関連する "ジャー地獄" として知られている古い問題です。

推移的な依存関係の場合、バージョン管理を制御することはできず、異なるバージョンが互換性があるという保証はありません。ロガーの小さなバージョン変更の単純なケースでは、互換性がある可能性があります。しかし、一般的なケースでは、あなたは葛藤に遭遇します。

OSGiこの問題を解決するために一部開発されました。個人的に私はApache Felix OSGiの実装を使用します。

この問題はJava ClassLoaderに起因します。同じパッケージとクラス名を持つ2つのクラスをロードすることはできません。つまり、制約を満たすためにslf4jの両方のバージョンをロードすることはできません。

OSGiは、JVMの上で動作するランタイムフレームワークです。デフォルトのクラスローダーを使用してJarを直接JVM上で実行するのではなく、OSGiインスタンス内でJarを実行します。 これには、Jarのマニフェストファイルにいくつかの追加メタデータが必要です。これらのJarはBundlesと呼ばれます。 OSGiは各バンドルに独自のClassLoaderを与え、推移的な依存関係の分離を可能にします。それぞれの依存関係は別々のバンドルになり、名前の衝突なしにバンドルの分離されたClassLoader内でslf4jのバージョンをロードすることができます。

+1

私は同意しません。 Mavenは、クラスパス上に1つのjarファイルしか存在しないようにすることで、 "jar hell"を回避します。 Mavenのドキュメントには、バージョン範囲を記述することによって、これらのバージョンをどのように制御できるかが記載されています。実際には私はこの機能を使用しません。 –

+1

OSGiは素晴らしい技術ですが、デプロイメントの依存関係管理に取り組んでいます。この質問は、** Mavenを使って、**ビルドされた時間依存性管理を扱っていました。 –

+1

@ MarkO'Connorクラスパス上に1つのjarファイルしか存在しないようにして、部分的に役立ちます。コードの一部がバージョン1.0(および2.0ではなく)にある特定のAPIを使用し、コードの別の部分がバージョン2.0(および1.0ではなく)にある特定のAPIを使用する場合、どのように動作するのですか? –

2

Mavenは、これらの種類の推移的な依存関係を管理し、クラスパス上に1つのバージョンのjarだけが存在するように設計されています。 Mavenのは

dependencyプラグインをやっているかを確認する方法

は、Mavenのは、(様々なのPOMスルーダウントロールと同じモジュールに対する依存関係を宣言した他の誰決定)あなたに代わってやっているものを紹介します。

[INFO] [dependency:tree] 
[INFO] org.apache.maven.plugins:maven-dependency-plugin:maven-plugin:2.0-alpha-5-SNAPSHOT 
[INFO] +- org.apache.maven.reporting:maven-reporting-impl:jar:2.0.4:compile 
[INFO] | \- commons-validator:commons-validator:jar:1.2.0:compile 
[INFO] |  \- commons-digester:commons-digester:jar:1.6:compile 
[INFO] |  \- (commons-collections:commons-collections:jar:2.1:compile - omitted for conflict with 2.0) 
[INFO] \- org.apache.maven.doxia:doxia-site-renderer:jar:1.0-alpha-8:compile 
[INFO] \- org.codehaus.plexus:plexus-velocity:jar:1.1.3:compile 
[INFO]  \- commons-collections:commons-collections:jar:2.0:compile 

は、通常、モジュールの最新バージョンが選択されているいくつかのモジュールは例えば、ログライブラリの最新バージョンでのみ利用可能な方法を使用している場合がありますように、これは理にかなっています。実際には、従属コードがロックステップで保持されていないときに、コンパイルの問題を引き起こす廃止予定のメソッドの削除が一般的です...何

を行うにMavenを伝える方法

あなたが選択したバージョンをより細かく制御したいなら、あなたは次のように依存関係のバージョンの範囲を指定する必要があります。

<dependency> 
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <version>[3.8,4.0)</version> 
    <scope>test</scope> 
</dependency> 

機能はここで説明されています。

これが役立ちます。

関連する問題