155 votes

Existe-t-il un moyen d'exclure les artefacts hérités d'un POM parent ?

Les artefacts des dépendances peuvent être exclus en déclarant un élément <exclusions> à l'intérieur d'un élément <dependency> Mais dans ce cas, il est nécessaire d'exclure un artefact hérité d'un projet parent. Voici un extrait du POM en question :

<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 dépend de l'artefact javax.mail:mail-1.4.jar y ALL-DEPS dépend d'une autre version de la même bibliothèque. En raison du fait que mail.jar de ALL-DEPS existent dans l'environnement d'exécution, bien qu'elles ne soient pas exportées, se heurtent à l'environnement d'exécution. mail.jar qui existe sur le parent, qui est scopé en tant que compile .

Une solution pourrait être de supprimer mail.jar du POM parent, mais la plupart des projets qui héritent de la base en ont besoin (c'est une dépendance transitive pour log4j). Ce que j'aimerais donc faire, c'est simplement exclure la bibliothèque du parent du projet de l'enfant comme cela pourrait être le cas si base était une dépendance et non le pom parent :

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

58voto

Pascal Thivent Points 295221

Quelques idées :

  1. Peut-être pourriez-vous simplement ne pas hériter du parent dans ce cas (et déclarer une dépendance à l'égard de base avec l'exclusion). Ce n'est pas pratique si vous avez beaucoup de choses dans le pom parent.

  2. Une autre chose à tester serait de déclarer l'élément mail avec la version requise par l'artefact ALL-DEPS dans le cadre de la dependencyManagement dans le pom parent pour forcer la convergence (bien que je ne sois pas sûr que cela résoudra le problème du scoping).

    <dependencyManagement> <dependencies> <dependency>
    <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>???</version><!-- put the "right" version here --> </dependency> </dependencies> </dependencyManagement>

  3. Vous pouvez également exclure le mail de log4j si vous n'utilisez pas les fonctionnalités qui en dépendent (et c'est ce que je ferais) :

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

  4. Vous pouvez aussi revenir à la version 1.2.14 de log4j au lieu de la version hérétique 1.2.15 (pourquoi n'ont-ils pas marqué les dépendances ci-dessus en tant que facultatif ? !).

39voto

timomeinen Points 595

Vous pouvez regrouper vos dépendances dans un projet différent avec le packaging pom tel que décrit par Sonatypes Meilleures pratiques :

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

et de les référencer à partir de votre "parent-pom" (surveillez les dépendances <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>

Votre projet-enfant hérite de ce projet-parent comme auparavant. Mais maintenant, la dépendance mail peut être exclue dans le projet enfant dans la section dependencyManagement bloc :

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

18voto

Sridhar-Sarnobat Points 965

Ne pas utiliser de pom parent

Cela peut sembler extrême, mais de la même manière que l'"enfer de l'héritage" est une raison pour laquelle certaines personnes tournent le dos à la programmation orientée objet (ou "Object Oriented Programming"). préférer la composition à l'héritage ), supprimer le problème des <parent> bloc et copier-coller Quoi qu'il en soit <dependencies> vous avez besoin (si votre équipe vous donne cette liberté).

L'hypothèse selon laquelle la division des poms en un parent et un enfant pour "réutiliser" et "éviter la redondance" devrait être ignorée et vous devriez d'abord répondre à vos besoins immédiats (le remède est pire que la maladie). En outre, la redondance a ses avantages, à savoir l'indépendance vis-à-vis des changements extérieurs (c'est-à-dire la stabilité).

C'est plus facile qu'il n'y paraît si vous générez le pom effectif (eclipse le fournit mais vous pouvez le générer depuis la ligne de commande avec mvn help:effective ).

Exemple

Je veux utiliser logback en tant que liaison slf4j, mais mon pom parent inclut le fichier log4j dépendance. Je ne veux pas avoir à pousser la dépendance des autres enfants à log4j dans leur propre dépendance à log4j. pom.xml afin que le mien soit libre.

11voto

Bax Points 643

Redéfinir la dépendance (dans le pom enfant) avec scope en montrant un bocal vide :

<dependency>
    <groupId>dependency.coming</groupId>
    <artifactId>from.parent</artifactId>
    <version>0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/empty.jar</systemPath>
</dependency>

Le jar peut contenir un seul fichier vide :

touch empty.txt
jar cvf empty.jar empty.txt

7voto

porterhouse91 Points 76

Avez-vous essayé de déclarer explicitement la version de mail.jar que vous voulez ? La résolution de dépendances de Maven devrait l'utiliser pour la résolution de dépendances avant toutes les autres versions.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X