web-dev-qa-db-ja.com

依存関係管理とスコープ

通常、<dependencyManagement>セクションにparent-project/pom.xmlセクションを配置します。この<dependencyManagement>セクションには、次のような子モジュールのすべての依存関係の宣言とバージョンが含まれています(つまり、<scope>要素なし):

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
    </dependency>
  </dependencies> 
</dependencyManagement>

すべての子モジュール(すなわちmoduleX/pom.xml)には、次のものがあります。

  <dependencies>
    <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <scope>test</scope>
    </dependency>
  </dependencies> 

明らかに、この例では、同じ依存関係に対して<scope>test</scope>を複数回繰り返しています(junitを必要とするすべての子モジュールで1回)。

私の質問は:
<scope>宣言に関するベストプラクティスは何ですか?
<dependencyManagement>に入れる方が良いですか?
それとも、(この投稿のように)子モジュールの<dependencies>セクションに配置する方が良いでしょうか?なぜ?
この質問に対する決定的な答えはありますか?

49
ben75

パーティーに少し遅れましたが、2セントを追加します。最近、デバッグが非常に難しい問題に遭遇しました。複数のプロジェクトにわたる依存関係を管理するための親POMがあります。それらに共通するすべての依存関係を設定し、groupId、artifactId、version、およびmost common scopeを含めました。私の考えでは、それが最も一般的なスコープに沿っていれば、各プロジェクトの実際の依存関係セクションにスコープを含める必要はないでしょう。問題は、それらの依存関係の一部が推移的な依存関係として現れたときに発生しました。たとえば

  • AはコンパイルスコープでBに依存します
  • BはコンパイルスコープでCに依存します
  • Cは、親のdependencyManagementで提供されるように設定されます。

次に、AのCへの推移的な依存関係が提供されると判断されます。それが理にかなっているかどうかは本当にわかりませんが、確かに混乱します。

とにかく、手間を省き、dependencyManagementからスコープを除外します。

46
Lucas

dependencyManagementは、すべてのプロジェクトサブモジュールの依存関係バージョンを定義するためのものです。このセクションの唯一の適切なスコープは、BOMのimportです。

スコープはdependenciesセクションで定義する必要があります。

(特定の依存関係について、使用状況を決定します。実行に必要な場合にのみ依存関係を含めることができます。たとえば、耳はJava-ee依存関係(scope provided )ターゲットサーバー上でそれらを見つけるため。)

[編集]

最初のステートメントには例外があり、providedセクションのスコープdependencyManagementは、dependenciesセクションの定義済みスコープをオーバーライドします。スコープを強制するには、 DependencyManagementを参照してください

20
Gab

他の回答と同様に、ベストプラクティスは、dependencyManagementからスコープを除外し、依存関係を定義するときにスコープを明示的に指定することです。異なるスコープで同じ依存関係の異なるバージョンが必要になることはまれなケースです。たとえば、アプリのコンパイル時に1つのバージョンを、実行時に別のバージョンを使用します。考えられる唯一のケースは、ユーザーが指定したバージョンではなくそのバージョンを使用する場合に、ライブラリの異なるバージョンに対してテストします。

DependencyManagementでスコープを定義すると、そのバージョンの使用が定義されたスコープのみに制限されるため、他のスコープは依存関係のランダムバージョンを取得します。昨日、テストスコープのdependencyManagementでjunit 4.12を定義したときにこれに遭遇しましたが、一般的なテストフレームワークモジュールはコンパイルスコープのjunitを使用したため、代わりにバージョン4.8.2を採用しました。

3
Phil

どのスコープでも、依存関係管理に単一の依存関係を追加してもメリットはありません。持っているのは複製だけです。バージョンを構成可能にする場合は、プロパティを追加し、依存関係で使用します。

<properties>
        <junit.version>4.10</junit.version> 
    ...
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
    </dependency>
</dependencies>

ただし、特定のバージョンのJava EE実装の使用など、より大きな成果物のコレクションのバージョンを調整するためにbomsを使用している場合、依存関係管理が光る場合があります。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.jboss.bom</groupId>
            <artifactId>jboss-javaee-6.0-with-tools</artifactId>
            <version>${javaee6.with.tools.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
....
2
kostja