依存関係からの成果物は、<exclusions>
内で<dependency>
要素を宣言することで除外できますが、この場合、親プロジェクトから継承された成果物を除外する必要があります。議論中のPOMの抜粋は次のとおりです。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>jruby</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<artifactId>base</artifactId>
<groupId>es.uniovi.innova</groupId>
<version>1.0.0</version>
</parent>
<dependencies>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>ALL-DEPS</artifactId>
<version>1.0</version>
<scope>provided</scope>
<type>pom</type>
</dependency>
</dependencies>
</project>
base
アーティファクト、javax.mail:mail-1.4.jar
に依存し、ALL-DEPS
は同じライブラリの別のバージョンに依存します。 mail.jar
のALL-DEPS
が実行環境に存在するという事実により、エクスポートされませんが、compile
としてスコープされる親に存在するmail.jar
と衝突します。
解決策として、親POMからmail.jarを削除することもできますが、baseを継承するほとんどのプロジェクトでは必要になります(log4jの推移的な依存関係と同様)。したがって、私がやりたいのは、単純に子プロジェクトから親のライブラリを除外するです。これは、base
が親pomではなく依存関係だった場合に実行できます。
...
<dependency>
<artifactId>base</artifactId>
<groupId>es.uniovi.innova</groupId>
<version>1.0.0</version>
<type>pom<type>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
</exclusions>
</dependency>
...
いくつかのアイデア:
その場合、単純に親から継承することはできません(そして、base
への依存関係を除外して宣言します)。親ポンにたくさんのものがある場合は便利ではありません。
テストする別のことは、親pomのmail
の下でALL-DEPS
に必要なバージョンでdependencyManagement
アーティファクトを宣言して、収束を強制することです(これはスコーピングの問題を解決するかわかりませんが)。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>???</version><!-- put the "right" version here -->
</dependency>
</dependencies>
</dependencyManagement>
mail
依存関係を除外できます(これが私がやることです):<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.Sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.Sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
</dependency>
Sonatypes ベストプラクティス で説明されているように、パッケージ化pom
を使用して、異なるプロジェクト内の依存関係をグループ化できます。
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>base-dependencies</artifactId>
<groupId>es.uniovi.innova</groupId>
<version>1.0.0</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
</project>
あなたの親pomからそれらを参照します(依存関係<type>pom</type>
を見てください):
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>base</artifactId>
<groupId>es.uniovi.innova</groupId>
<version>1.0.0</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<artifactId>base-dependencies</artifactId>
<groupId>es.uniovi.innova</groupId>
<version>1.0.0</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
子プロジェクトは、以前と同様にこの親ポンを継承します。しかし今、メール依存関係はdependencyManagement
ブロック内の子プロジェクトで除外できます:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>jruby</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<artifactId>base</artifactId>
<groupId>es.uniovi.innova</groupId>
<version>1.0.0</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<artifactId>base-dependencies</artifactId>
<groupId>es.uniovi.innova</groupId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
</project>
これは極端に聞こえるかもしれませんが、同じように「継承地獄」が一部の人々がオブジェクト指向プログラミングに背を向ける理由であり、問題のある<parent>
ブロックと コピーと貼り付け 何でも<dependencies>
あなたが必要です。
「再利用」と「冗長性の回避」のために、pomsを親と子に分割するという仮定は無視されるべきであり、まずは当面のニーズを満たす必要があります。 「治癒」は病気よりも最悪です。その上、冗長性には利点があります。つまり、外部変更の独立性(安定性)です。
これは、効果的なpomを生成する場合に聞こえるよりも簡単です(Eclipseはそれを提供しますが、mvn help:effective
を使用してコマンドラインから生成できます)。
Slf4jバインディングとしてlogback
を使用したいのですが、親pomにはlog4j
依存関係が含まれています。私は行きたくないし、他の子供たちのlog4jへの依存を自分のpom.xml
ファイルに押し下げて、私の物が邪魔されないようにしなければなりません。
空のjarを指すscope
システムで依存関係を(子pomで)再定義します。
<dependency>
<groupId>dependency.coming</groupId>
<artifactId>from.parent</artifactId>
<version>0</version>
<scope>system</scope>
<systemPath>${project.basedir}/empty.jar</systemPath>
</dependency>
Jarには、空のファイルを1つだけ含めることができます。
touch empty.txt
jar cvf empty.txt
必要なmail.jarのバージョンを明示的に宣言しようとしましたか? Mavenの依存関係の解決では、これを他のすべてのバージョンの依存関係の解決に使用する必要があります。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>jruby</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<artifactId>base</artifactId>
<groupId>es.uniovi.innova</groupId>
<version>1.0.0</version>
</parent>
<dependencies>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>VERSION-#</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>ALL-DEPS</artifactId>
<version>1.0</version>
<scope>provided</scope>
<type>pom</type>
</dependency>
</dependencies>
</project>
最善の策は、常に非推移的に継承したくない依存関係を作成することです。
これを行うには、提供されたスコープを使用して親pomでそれらをマークします。
親がこれらの依存関係のバージョンを管理したい場合は、<dependencyManagement>
タグを使用して、明示的に継承したり、その継承を子に渡すことなく、必要なバージョンを設定できます。
パッケージを呼び出しても、その依存関係の一部が必要ない場合は、次のようなことができます(この場合、新しいlog4jを使用する必要があるため、古いlog4jを追加したくありませんでした)。
<dependency>
<groupId>package</groupId>
<artifactId>package-pk</artifactId>
<version>${package-pk.version}</version>
<exclusions>
<exclusion>
<groupId>org.Apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.Apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- LOG4J -->
<dependency>
<groupId>org.Apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.Apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.5</version>
</dependency>
これは私にとってはうまくいきます...しかし、私はJava/mavenが初めてなので、おそらく最適ではありません。
私は本当にこの汚いことをする必要がありました...
それらの依存関係をスコープtest
で再定義しました。スコープprovided
は機能しませんでした。
Fat jarを作成するために、Spring Bootプラグインを使用します。 Springfox swagger-2などの共通ライブラリを定義するモジュールcommonがあります。私super-serviceには親commonが必要です(不要です)そうするが、会社の規則は強制する!)
だから私の親やコモンズにはポンポンがあります。
<dependencyManagement>
<!- I do not need Springfox in one child but in others ->
<dependencies>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>${swagger.version}</version>
</dependency>
<!- All services need them ->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.Apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${Apache.poi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
そして、私のsuper-servicepom。
<name>super-service</name>
<parent>
<groupId>com.company</groupId>
<artifactId>common</artifactId>
<version>1</version>
</parent>
<dependencies>
<!- I don't need them ->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-core</artifactId>
<version>2.8.0</version>
<scope>test</scope>
</dependency>
<!- Required dependencies ->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.Apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
</dependencies>
これは最終的なファットアーティファクトのサイズです
82.3 MB (86,351,753 bytes) - redefined dependency with scope test
86.1 MB (90,335,466 bytes) - redefined dependency with scope provided
86.1 MB (90,335,489 bytes) - without exclusion
また、この答えは言及する価値があります-私はそうしたかったのですが、私は怠け者です... https://stackoverflow.com/a/48103554/4587961