とにかく、親POMから継承されたアーティファクトを除外する方法はありますか?


119

依存関係からのアーティファクトは、<exclusions>要素をa内で宣言することによって除外できますが<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.jarALL-DEPS同じライブラリの別のバージョンに依存しています。事実によるものmail.jarからALL-DEPSエクスポートされていないが、と衝突実行環境上に存在する、mail.jarとしてスコープされた親、上に存在することcompile

解決策は、親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>
...

回答:


49

いくつかのアイデア:

  1. その場合は、親から継承できないだけかもしれません(そして、依存関係をbase除外で宣言します)。親のポンポンにたくさんのものがある場合は便利ではありません。

  2. テストへのもう一つは、宣言するだろうmailことにより、必要なバージョンでアーティファクトをALL-DEPS下にdependencyManagement(私は必ずこれはスコープの問題を解決するわけではないんですが)収束を強制するために、親ポンポンインチ

<dependencyManagement>
  <dependencies>
    <dependency>    
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>???</version><!-- put the "right" version here -->
    </dependency>
  </dependencies>
</dependencyManagement>
  1. またはmail、log4jに依存する機能を使用していない場合は、依存関係をlog4jから除外できます(これが私が行うことです)。
<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>
  1. または、異端の1.2.15バージョンではなく、log4jのバージョン1.2.14に戻すこともできます(なぜ、上記の依存関係をオプションとしてマークしなかったのですか?!)。

お返事をありがとうございます。役立つ情報がたくさん含まれています。1)について気づいたように、親pomには、baseが依存関係としてマークされた場合に推移的に解決される依存関係だけでなく、会社のすべてのプロジェクト間で再利用される一般的なレポート、ソース管理、およびその他のものも含まれているため、最適ではありません。2)に関しては、私はそれを試しましたが、提供されたアーティファクトのスコープを指定して、それはうまくいきました:) 最初は、コンパイルが提供よりも優先されるため機能しないと思っていましたが、幸いにも間違っていました(子POMが親の構成をオーバーライドします)。
Miguel

29

pomSonatypes Best Practicesで説明されているように、パッケージ化を使用して別のプロジェクト内で依存関係をグループ化できます。

<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>

あなたの子プロジェクトは以前のようにこの親pomを継承します。しかし今では、メールの依存関係は、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>

4
+1ですが、子pomは<dependencyManagement>ではなく<dependencies>セクションを使用する必要があります。後者は、親pom内から依存関係のバージョンを管理するためです。
マシューワイズ2014年

1
これはBOM、別名部品表としても知られています:-)
Pim Hazebroek

これは推移的な依存関係でのみ機能しますか?私の親のpomにはlog4jが含まれているため、私のpomのログバックが正しく機能していません。
Sridhar Sarnobat

10

親のポンポンを使用しないでください

これは極端に聞こえるかもしれませんが、「継承地獄」と同じように、一部の人々はオブジェクト指向プログラミングに背を向け(または継承よりも構成を好む)、問題のある<parent>ブロックを削除し、何でもコピーして貼り付けます<dependencies>必要をます(チームがあなたに与えた場合)この自由)。

「再利用」および「冗長性の回避」のためにポンポンを親子に分割するという仮定は無視する必要があり、最初に緊急のニーズに対応する必要があります(治療法は病気よりも最悪です)。さらに、冗長性にはその利点があります。つまり、外部の変更の独立性(つまり、安定性)です。

これは、効果的なpomを生成した場合(Eclipseで提供されますが、コマンドラインから mvn help:effective)。

logbackslf4jバインディングとして使用したいのですが、親pomにlog4j依存関係が含まれています。私は行きたくないので、他の子供たちのlog4jへの依存を自分のpom.xmlファイルにプッシュして、私の物が妨げられないようにする必要があります。


1
親のpomの更新されたバージョンを使用する必要がある場合、将来のメンテナがこれをやり直す必要があるため、これ(および実行した手順)を非常に注意深く文書化してください。
するThorbjörnRavnアンデルセン

確かに、親pomで依存関係を使用しないことを意味しますか?親pomは依然、依存関係のバージョンや一般的なプラグインを管理するのに非常に便利です。依存関係を注入するためにそれを使用するだけで逆効果が発生する可能性があります
Amit Goldstein

いいえ、軽量の親pomを使用すると言っているわけではありません。他のアプリは親のpom内の不要なジャンクに依存しているため、チームの他のユーザーは親のpomをトリミングできません。
Sridhar Sarnobat

8

scope空のjarを指すシステムで(子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

私が実行しなければならなかったのWindows 10上で、あなたの答えをありがとうnotepad empty.class、その後jar cvf empty.jar empty.class、空のjarを生成します。
Rov

1
悪い習慣のように見える
PiotrŻak

6

必要な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>

1
Pascalの回避策#2も有効であるため、実際には、メールの依存関係を規定どおりに宣言する必要があることも考慮に入れました。ありがとうございました。
Miguel

提供されたスコープは私にとってはうまくいきませんでした。スコープテストを使用しました。私の答えを確認してください。 stackoverflow.com/a/55970293/4587961
Yan Khonski、

3

最善の策は、常に継承したくない依存関係を自動詞化することです。

これを行うには、スコープを指定して、親pomでマークします。

それでも親にこれらのdepのバージョンを管理させたい場合は、<dependencyManagement>タグを使用して、明示的に継承したり、その継承を子に渡したりせずに、必要なバージョンをセットアップできます。


1

パッケージを呼び出したが、その依存関係の一部が不要な場合は、次のようにすることができます(この場合、新しいものを使用する必要があったため、古い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にかなり慣れていないので、おそらく最適ではありません。


Stack Overflowへようこそ。私が常に質問を却下している失礼な人々に投稿をやめさせないでください。
Sridhar Sarnobat

1

私はこの汚いことをする必要が本当にありました...

これらの依存関係をスコープで再定義しましたtest。スコープprovidedが機能しませんでした。

Spring Bootプラグインを使用してファットjarをビルドします。私たちは、モジュール持っている一般的な例Springfoxを闊歩-2のために、共通のライブラリを定義します。私のスーパーサービスには親を共有する必要があります(そうしたくないのですが、会社のルールが強制します!)

だから私の両親やコモンズはポンポンを持っています。

<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>

そして私のスーパーサービスのポン。

<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


0

親pomをタイプpomの依存関係として追加し、それを除外できます。とにかく親pomがダウンロードされるからです。これは私のために働いた

<dependency>
  <groupId>com.abc.boot</groupId>
  <artifactId>abc-boot-starter-parent</artifactId>
  <version>2.1.5.RELEASE</version>
  <type>pom</type>
  <exclusions>
    <exclusion>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
    </exclusion>
  </exclusions>   
</dependency>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.