1. 概要

MavenはJavaエコシステムで最も人気のあるビルドツールの1つであり、そのコア機能の1つは依存関係の管理です。

このチュートリアルでは、Mavenプロジェクトの推移的な依存関係(依存関係スコープ)の管理に役立つメカニズムについて説明し、調査します。

2. 推移的な依存関係

Mavenには、直接と推移の2種類の依存関係があります。

直接の依存関係は、プロジェクトに明示的に含めるものです。

これらは、を使用して含めることができますタグ:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

一方、推移的な依存関係は直接的な依存関係によって必要になります。 Mavenは、必要な推移的な依存関係をプロジェクトに自動的に含めます。

mvndependency:tree コマンドを使用して、プロジェクト内の推移的な依存関係を含むすべての依存関係を一覧表示できます。

3. 依存関係の範囲

依存関係スコープは、依存関係の推移性を制限するのに役立ちます。 また、さまざまなビルドタスクのクラスパスを変更します。 Mavenには6つのデフォルトの依存関係スコープがあります。

また、 import を除く各スコープは、一時的な依存関係に影響を与えることを理解することが重要です。

3.1. コンパイル

これは、他のスコープが提供されていない場合のデフォルトのスコープです。

このスコープの依存関係は、すべてのビルドタスクのプロジェクトのクラスパスで利用できます。 それらは、依存プロジェクトにも伝播されます。

さらに重要なことに、これらの依存関係も推移的です。

<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>

3.2. 提供された

このスコープを使用して、実行時にJDKまたはコンテナーによって提供される必要がある依存関係をマークします。

このスコープの適切なユースケースは、コンテナーが既にいくつかのライブラリー自体を提供している、いくつかのコンテナーにデプロイされたWebアプリケーションです。 たとえば、これは実行時にサーブレットAPIをすでに提供しているWebサーバーである可能性があります。

私たちのプロジェクトでは、提供されたスコープでこれらの依存関係を定義できます。

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

が提供する依存関係は、コンパイル時およびプロジェクトのテストクラスパスでのみ使用できます。 これらの依存関係も推移的ではありません。

3.3. ランタイム

このスコープとの依存関係は実行時に必要です。ただし、プロジェクトコードのコンパイルには依存関係は必要ありません。 そのため、 runtime スコープでマークされた依存関係は、ランタイムおよびテストクラスパスに存在しますが、コンパイルクラスパスには含まれません。

JDBCドライバーは、ランタイムスコープを使用する必要がある依存関係の良い例です。

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.28</version>
    <scope>runtime</scope>
</dependency>

3.4. テスト

このスコープを使用して、アプリケーションの標準の実行時に依存関係が必要ではなく、テスト目的でのみ使用されることを示します。

Test の依存関係は推移的ではなく、テストおよび実行クラスパスにのみ存在します。

このスコープの標準的なユースケースは、JUnitなどのテストライブラリをアプリケーションに追加することです。

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

3.5. システム

システムスコープは、提供されているスコープと非常によく似ています。主な違いは、システムでは、システム上の特定のjarを直接指す必要があることです。

システムスコープは非推奨になっていることに言及する価値があります。

覚えておくべき重要なことは、 system スコープの依存関係を使用してプロジェクトを構築すると、依存関係が存在しないか、 systemPath が指す場所とは異なる場所にある場合、異なるマシンで失敗する可能性があることです。 :

<dependency>
    <groupId>com.baeldung</groupId>
    <artifactId>custom-dependency</artifactId>
    <version>1.3.2</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/libs/custom-dependency-1.3.2.jar</systemPath>
</dependency>

3.6. 輸入

依存関係タイプpomでのみ使用できます。

import は、この依存関係を、そのPOMで宣言されているすべての有効な依存関係に置き換える必要があることを示します。

この下でカスタムプロジェクト依存関係は、カスタムプロジェクトで宣言されたすべての依存関係に置き換えられます pom.xml セクション。

<dependency>
    <groupId>com.baeldung</groupId>
    <artifactId>custom-project</artifactId>
    <version>1.3.2</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

4. スコープとトランジティビティ

各依存関係スコープは、独自の方法で推移的な依存関係に影響を与えます。 これは、異なる推移的な依存関係が、異なるスコープを持つプロジェクトに含まれる可能性があることを意味します。

ただし、スコープが提供するおよびテストの依存関係は、メインプロジェクトに含まれることはありません。

これが何を意味するのかを詳しく見てみましょう。

  • compile スコープの場合、 runtime スコープのすべての依存関係は、プロジェクトの runtime スコープに取り込まれ、compileのすべての依存関係はスコープは、プロジェクトのcompileスコープでプルされます。
  • 提供スコープの場合、ランタイムコンパイルの両方のスコープ依存関係が、プロジェクトの提供スコープに取り込まれます。
  • テストスコープの場合、ランタイムコンパイルスコープの両方の推移的な依存関係が、プロジェクトのテストスコープに取り込まれます。
  • runtime スコープの場合、runtimeスコープとcompileスコープの両方の推移的な依存関係が、プロジェクトのruntimeスコープに取り込まれます。

5. 結論

この簡単な記事では、Mavenの依存関係スコープ、その目的、およびそれらの動作の詳細に焦点を当てました。

Mavenをさらに深く掘り下げるには、ドキュメントから始めるのが最適です。