実行時とコンパイル時の違いと、この2つを区別する方法は理解していますが、コンパイル時と実行時の依存関係を区別する必要はありません。
一般的なコンパイル時とランタイムの概念、およびMaven固有の依存関係compile
とruntime
スコープの依存関係は2つの非常に異なるものです。これらは同じフレームを持たないため、直接比較することはできません。一般的なコンパイルとランタイムの概念は広範ですが、Mavencompile
とruntime
スコープの概念は、具体的には、コンパイルまたは実行の時間に応じた依存関係の可用性/可視性に関するものです。
Mavenは何よりもjavac
/java
ラッパーであり、Javaには、指定するコンパイル時のクラスパスと、で指定javac -cp ...
するランタイムクラスパスがあることを忘れないでくださいjava -cp ...
。MavenスコープをJavaコンパイルとランタイムclassppathの両方に依存関係を追加する方法
と見なすことは間違いではありません(compile
javac
およびjava
)Mavenruntime
スコープは、Javaランタイムclassppath()でのみ依存関係を追加する方法と見なすことができますjavac
。
私が窒息しているのはこれです:プログラムがコンパイル中に依存していた実行時に何かに依存しないようにするにはどうすればよいですか?
runtime
あなたが説明することは、compile
範囲とは何の関係もありません。依存関係をコンパイル時に依存するように指定するスコープには、実行時ではなく、
より多くのように見えます。
コンパイルに依存関係が必要なために使用しますが、依存関係は環境によってすでに提供されているため、パッケージ化されたコンポーネント(JAR、WARなど)に含めたくありません。サーバーまたはその他に含めることができます。 Javaアプリケーションとして指定されたクラスパスのパスが開始されます。 provided
私のJavaアプリがlog4jを使用している場合、コンパイル(log4j内からメンバーメソッドと統合して呼び出すコード)とランタイム(私のコードはlog4j内のコードで何が起こるかを完全に制御できません)のためにlog4j.jarファイルが必要です.jarが実行されます)。
この場合はそうです。ただし、後で別のロギング実装(log4J 2、logbackなど)に切り替えることができるように、log4jの前のファサードとしてslf4jに依存するポータブルコードを作成する必要があるとします。
この場合、pomではslf4jをcompile
依存関係として指定する必要があります(これがデフォルトです)が、log4jの依存関係を依存関係として指定しますruntime
。
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>...</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>...</version>
<scope>runtime</scope>
</dependency>
このように、コンパイルされたコードでlog4jクラスを参照することはできませんでしたが、slf4jクラスを参照することはできます。
時間とともに2つの依存関係を指定した場合compile
、コンパイルされたコードでlog4jクラスを参照することを妨げるものは何もないため、ロギング実装との望ましくない結合を作成する可能性があります。
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>...</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>...</version>
</dependency>
runtime
スコープの一般的な使用法は、JDBC依存関係宣言です。ポータブルコードを作成するには、クライアントコードが特定のDBMS依存関係(例:PostgreSQL JDBC依存関係)のクラスを参照することは望ましくありませんが、実行時にクラスを作成するために必要なのと同じように、アプリケーションに含める必要があります。 JDBCAPIはこのDBMSで動作します。