MavenスコープのコンパイルとJARパッケージ用に提供されたものの違い


260

MavenスコープcompileprovidedアーティファクトがJARとして構築される場合の違いは何ですか?それがWARであれば、私は理解します-アーティファクトはWEB-INF / libに含まれるか含まれないでしょう。ただし、JARの場合は関係ありません。依存関係は含まれません。スコープがcompileまたはの場合、クラスパス上になければなりませんprovidedprovided依存関係が推移的でないことは知っていますが、それは1つの違いだけですか?

回答:


289

Maven Docから:

  • コンパイル

    これはデフォルトのスコープであり、何も指定されていない場合に使用されます。コンパイルの依存関係は、プロジェクトのすべてのクラスパスで使用できます。さらに、これらの依存関係は依存プロジェクトに伝達されます。

  • 提供

    これはコンパイルによく似ていますが、JDKまたはコンテナが実行時に依存関係を提供することを期待していることを示しています。たとえば、Java Enterprise EditionのWebアプリケーションを構築する場合、Webコンテナがこれらのクラスを提供するため、サーブレットAPIおよび関連するJava EE APIへの依存関係を提供されたスコープに設定します。このスコープは、コンパイルとテストのクラスパスでのみ使用でき、推移的ではありません。

要約:

  • 依存関係は推移的ではありません(あなたが言及したように)
  • 提供されたスコープはコンパイルとテストのクラスパスでのみ使用できますが、コンパイルスコープはすべてのクラスパスで使用できます。
  • 提供された依存関係はパッケージ化されていません

5
はい、知っています。しかし、JAR packagingコンテキスト内のスコープの違いについて考えます。Maven docはそれについて言及していません。私はしばらくの間Mavenを使用していますが、私はすでにそれについて自分自身に質問しました:)したがって、JAR packagingコンテキストではcompileprovided(依存関係の移行を除いて)の間に違いはないようです。私は正しいですか?
emstol

3
@Jacob「コンパイルスコープがすべてのクラスパスで利用可能であるのに対して」とはどういう意味ですか?
オタク、2013

1
「NOT Transitive」がここでの大きなキャッチです。依存関係の地獄は開発者が非常に頻繁に直面する問題であり、提供されたスコープはそれを妨げ、他のバージョンとの干渉が重要です。
Seetharamani Tmr 2017年

2
違いはパッケージングの段階だと思います。コンパイルすると、最終的な戦争またはjar(スプリングブート実行可能jarなど)にjarが含まれ、提供されない場合があります。提供されたjarはWebコンテナー(ext libフォルダーに入れるなど)によって提供される可能性があるため、他のスコープ、コンパイル、ランタイムに依存していない場合、WARパッケージには含まれません。
Addo Zhang

1
@emstol元の質問に戻りますが、JARの場合、依存関係はJAR自体にパッケージ化されていません。しかし、mavenでは、JARパッケージはライブラリとして使用することを意味します。それを他のいくつかのmavenプロジェクトにインポートするとすぐに、スコープがそうである場合は推移的な依存関係がもたらされ、スコープがcompileそうでない場合はそうではありませんprovided
LeoLuz

291

コンパイルとは、アプリをコンパイルして実行するためにJARが必要であることを意味します。Webアプリケーションの場合、例として、JARはWEB-INF / libディレクトリに配置されます。

提供されるとは、コンパイルにJARが必要であることを意味しますが、実行時にはすでに環境によって提供されるJARが存在するため、アプリにパッケージ化する必要はありません。Webアプリの場合、これはJARファイルがWEB-INF / libディレクトリーに配置されないことを意味します。

Webアプリの場合、アプリサーバーがすでにJAR(またはその機能)を提供している場合は、「提供」を使用します。それ以外の場合は「コンパイル」を使用します。

こちらが参考です。


11
OPの質問に答えていませんか?' アーティファクトがJARとしてビルドされるときに提供されるmavenスコープコンパイルの使用の違いは何ですか?'作者が戦争としてパッケージ化するときの違いを知っていると明示的に述べていることに注意してください。
アルベルト

同じアプリケーションサーバーにデプロイされた別のJARを参照している場合、provideを使用できますか?
Samy Omar

1
したがって、明確にするために、mvn exec:java実行時に、提供された依存関係はクラスパスに追加されませんが、コンパイルされた依存関係は追加されます。
ジェイミー

私はこの質問をしました-stackoverflow.com/questions/37360132/…この問題は、スコープを提供からコンパイルに変更することで解決されました。しかし、「提供」スコープでコンパイルされたjarと「コンパイル」スコープでコンパイルされたjarの間に違いはありません。理由を教えてください。
Pavel_K 2016年


22

すべての依存関係(一般的なxxxx-all.jar)を含む単一のJARファイルを生成する場合は、提供されるスコープが重要です。このスコープ内のクラスは、生成されるJARにパッケージ化されないためです。

詳細については、maven-assembly-pluginを参照してください


7
提供される依存関係==>依存関係はパッケージ化されません
Gab是好人

3
OPの混乱はmaven-assembly-plugin、でパッケージ化すると明らかに解決されます。興味深いのは、最も投票された回答で言及されていないことです。
Henrique G. Abreu

この答えがわかりません。コメントのように見えます。
reinierpost 2017年

11
  • コンパイル

クラスパスで利用可能にします。通常のjarである場合、この依存関係を最終的なjarに追加しないでください。ただし、最終的なjarが単一のjarである場合(たとえば、実行可能jar)、このjarをjarに追加します。

  • 提供

依存関係はランタイム環境で使用できるため、この依存関係を追加しないでください。単一のjar(つまり、実行可能なjarなど)に含まれていない


3

jarファイルの場合、maven-jar-plugin構成でaddClassPathがtrueに設定されている場合、jarに含まれているMANIFEST.MFファイルにリストされているクラスパスに違いがあります。「コンパイル」依存関係はマニフェストに表示されますが、「提供」依存関係は表示されません。

私のペットのおしっこの1つは、これら2つの単語の時制が同じであるべきだということです。コンパイルして提供するか、コンパイルして提供します。


0

mavenスコープをに設定providedすると、プラグインの実行時に使用される実際の依存関係のバージョンは、インストールしたApache Mavenのバージョンによって異なります。


0

jarファイルが実行可能なスプリングブートjarファイルのような場合、すべての依存関係のスコープcompileはすべてのjarファイルを含める必要があります。

ただし、jarファイルが他のパッケージまたはアプリケーションで使用されている場合、これらのパッケージまたはアプリケーションが他の依存関係を提供できるため、jarファイルにすべての依存関係を含める必要はありません。

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