Maven:ライブラリーによって追加された依存関係をオーバーライドする方法


116

これが私の一般的な問題です:

私のプロジェクトPは、バージョン1.0.1のDに依存するCに依存するBに依存するAに依存しています。

Dのバージョン1.0.1に問題があり、別のモジュールを強制的に使用したい。Dへの依存関係を直接追加していないため、プロジェクトのPOMでこれを宣言する方法がわかりません。Dへの依存を宣言したのはCです。

重要:この場合、バージョンだけでなく、グループとアーティファクトも変更されます。したがって、依存関係のバージョンをオーバーライドするだけでなく、モジュールを除外して別のモジュールを含めることも重要です。

具体的なケースでは、Dは1.0.1にバグがあるStAX です。バグのメモによると、「問題はstax-api-1.0.1(maven GroupId = stax)をstax-api-1.0-2(maven GroupId = javax.xml.stream)に置き換えることで解決された」ので、ちょうどそれを試みています。

したがって、D = stax:stax-api:jar:1.0.1およびC = org.apache.xmlbeans:xmlbeans:jar:2.3.0

必要に応じて、Maven 2.0.9を使用しています。

mvn dependency:treeの出力

mvn dependency:tree
[..snip..]
[INFO] +- org.apache.poi:poi-ooxml:jar:3.6:compile
[INFO] |  +- org.apache.poi:poi-ooxml-schemas:jar:3.6:compile
[INFO] |  |  +- org.apache.xmlbeans:xmlbeans:jar:2.3.0:compile
[INFO] |  |  |  \- stax:stax-api:jar:1.0.1:compile

私のプロジェクトのPOMでは、「A」に次の依存関係があります。

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.6</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.6</version>
</dependency>

前もって感謝します。

回答:


100

現在のpomでバージョンを指定するだけです。ここで指定されたバージョンは、他を上書きします。

バージョン
強制特定のバージョンで現在のPOMで宣言されている場合、バージョンは常に優先されます。ただし、推移的な依存関係の使用に依存している場合、これは他のダウンストリームにも影響することに注意してください。


リソース:


5
Dへの依存関係を宣言していないため、バージョンを指定する方法が明確ではありません。また、最初のリンクには、「このドキュメントでは、Maven 2.0にまだ実装されていない依存関係管理の残りの要件について説明します。特に推移的な依存関係に関して。」頂点で。
wishihadabettername 2010年

@wishihadabettername、他のドキュメントで述べたように、「AのD 2.0に依存関係を明示的に追加して、D 2.0の使用を強制できます」
Colin Hebert

1
実際には、同じ<dependency>エントリを自分のpomに複製します。依存関係で、必要な<version>を指定します。これにより、「より深い」依存関係で使用されるすべてのバージョンが上書きされます。
キー

27

または、不要な依存関係を除外することもできます。STAXはJDK 1.6に含まれているため、1.6を使用している場合は完全に除外できます。

以下の私の例はあなたにとって少し間違っています-あなたは2つの除外のうちの1つだけが必要ですが、どちらがどちらかはよくわかりません。他のバージョンのStaxが浮かんでいます。以下の例では、Aをインポートし、Bをインポートし、CとDをインポートしました(それぞれより推移的な依存関係により)異なるバージョンのStaxをインポートしました。したがって、 'A'への依存関係で、両方のバージョンのStaxを除外しました。

<dependency>
  <groupId>a.group</groupId>
  <artifactId>a.artifact</artifactId>
  <version>a.version</version>
  <exclusions>
    <!--  STAX comes with Java 1.6 -->
    <exclusion>
      <artifactId>stax-api</artifactId>
      <groupId>javax.xml.stream</groupId>
    </exclusion>
    <exclusion>
      <artifactId>stax-api</artifactId>
      <groupId>stax</groupId>
    </exclusion>
  </exclusions>
<dependency>

1
この推移的な依存関係が使用される可能性があり、必要な場合に除外するとビルドが失敗する可能性があることに注意する必要があります。
Bernhard Colby

最新のJDK(つまり1.6+)を使用していて、推移的な依存関係を介して含まれるはるかに古いバージョンのstaxが必要な場合は、おそらくあらゆる種類のひどいランタイムクラスローダーの問題が発生します。私のアドバイス:JDKの1つを使用してください。「ビルドエラー」が発生した場合は、アップグレードが必要な何らかの形式の古いAPIに依存しています。または:JDKを1.5にロールバックします。幸運を祈ります。
スコット

10

また、サードパーティのライブラリの依存関係を無効にするのにも問題がありました。私はスコットのアプローチを除外に使用しましたが、ポンの新しいバージョンとの依存関係も追加しました。(私はMaven 3.3.3を使用しました)

したがって、stAXの例では次のようになります。

<dependency>
  <groupId>a.group</groupId>
  <artifactId>a.artifact</artifactId>
  <version>a.version</version>
  <exclusions>
    <!--  STAX comes with Java 1.6 -->
    <exclusion>
      <artifactId>stax-api</artifactId>
      <groupId>javax.xml.stream</groupId>
    </exclusion>
    <exclusion>
      <artifactId>stax-api</artifactId>
      <groupId>stax</groupId>
    </exclusion>
  </exclusions>
<dependency>

<dependency>
    <groupId>javax.xml.stream</groupId>
    <artifactId>stax-api</artifactId>
    <version>1.0-2</version>
</dependency>

10

</dependencies>ルートpomのタグ内に配置したものは、ルートpomのすべての子モジュールに含まれます。すべてのモジュールがその依存関係を使用している場合、これが方法です。

ただし、子モジュールの10のうち3つだけが依存関係を使用している場合、この依存関係をすべての子モジュールに含めたくありません。その場合は、依存関係を内に置くだけ</dependencyManagement>です。これにより、依存関係を必要とするすべての子モジュールが独自のpomファイルで宣言する必要がありますが、</dependencyManagement>タグで指定されているのと同じバージョンの依存関係が使用されます。

</dependencyManagement>最上位のpomファイルで宣言されたバージョンが使用されるため、を使用して推移的な依存関係で使用されるバージョンを変更することもできます。これは、プロジェクトAに別の外部プロジェクトC v1.0を含む外部プロジェクトB v1.0が含まれている場合に役立ちます。時々、セキュリティ違反がプロジェクトC v1.0で見つかり、v1.1で修正されますが、Bの開発者は、プロジェクトを更新してCのv1.1を使用するのに時間がかかります。その場合、単純に次のように宣言できます。 `内のプロジェクトのルートpom内のC v1.1への依存性、およびすべてが良好です(B v1.0が引き続きC v1.1でコンパイルできると仮定)。


1

正解は正解ですが、2セント追加したいと思います。プロジェクトAに依存関係としてプロジェクトBがあるという問題に遭遇しました。どちらのプロジェクトもslf4jを使用しますが、プロジェクトBはlog4jを使用し、プロジェクトAはlogbackを使用します。プロジェクトBはslf4j 1.6.1を使用しますが、プロジェクトAはslf4j 1.7.5を使用します(すでに含まれているlogback 1.2.3依存関係のため)。

問題:プロジェクトAがslf4j 1.7.5に存在する関数を見つけられず、eclipeの依存関係の階層タブを確認した後、ビルド中にlogbackのslf4j 1.7.5を使用する代わりにプロジェクトBのslf4j 1.6.1を使用していることがわかりました。

プロジェクトAのpomの依存関係の順序を変更して問題を解決しました。プロジェクトBのエントリをログバックエントリの下に移動すると、mavenがslf4j 1.7.5を使用してプロジェクトのビルドを開始しました。

編集: プロジェクトBの依存関係が機能する前に、slf4j 1.7.5依存関係を追加しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.