web-dev-qa-db-fra.com

Exclure toutes les dépendances transitives d'une dépendance unique

Dans Maven2, pour exclure une seule dépendance transitive, je dois faire quelque chose comme ceci:

<dependency>
  <groupId>sample.group</groupId>
  <artifactId>sample-artifactB</artifactId>
  <version>1</version>
   <exclusions>
     <exclusion>
       <groupId>sample.group</groupId>
       <artifactId>sample-artifactAB</artifactId>
     </exclusion>
   </exclusions>
</dependency>

Le problème avec cette approche est que je dois le faire pour chaque dépendance transitive apportée par sample-artifactB.

Existe-t-il un moyen d'utiliser une sorte de caractère générique pour exclure toutes les dépendances transitives en même temps au lieu d'une par une?

205
pbreault

Pour maven2, il n'y a pas moyen de faire ce que vous décrivez. Pour Maven 3, il y en a. Si vous utilisez Maven 3, veuillez vous reporter à autre réponse à cette question

Pour maven 2, je vous recommande de créer votre propre pom personnalisé pour la dépendance qui contient vos <exclusions>. Pour les projets qui doivent utiliser cette dépendance, définissez la dépendance sur votre pom personnalisé au lieu de l'artefact typique. Bien que cela ne vous permette pas nécessairement d'exclure toutes les dépendances transitives avec une seule <exclusion>, cela vous permet d'écrire votre dépendance une seule fois et que tous vos projets n'ont pas besoin de gérer des listes d'exclusions longues et inutiles.

51
whaley

Ce qui a fonctionné pour moi (peut-être une nouvelle fonctionnalité de Maven) consiste simplement à utiliser des caractères génériques dans l'élément d'exclusion.

J'ai un projet multi-module qui contient un module "app" qui est référencé dans deux modules fournis par WAR. L'un de ces modules emballés dans WAR n'a vraiment besoin que des classes de domaine (et je ne les ai pas encore séparées du module de l'application). J'ai trouvé que cela fonctionne:

<dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>app</artifactId>
    <version>${project.version}</version>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Le caractère générique à la fois sur groupId et artifactId exclut toutes les dépendances qui se propageraient normalement au module utilisant cette dépendance.

279
enricopulatzo

Une chose que j'ai trouvée utile:

Si vous placez la dépendance avec les exclusions dans la section dependencyManagement du POM parent de votre projet ou dans un POM de gestion des dépendances importable, vous n'avez pas besoin de répéter l'exclusion (ou la version).

Par exemple, si votre POM parent a:

<dependencyManagement>
    <dependencies>
    ...         
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.1</version>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
     ....
  </dependencies>
</dependencyManagement>

Ensuite, les modules de votre projet peuvent simplement déclarer la dépendance en tant que:

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>

Le POM parent spécifie à la fois la version et les exclusions. J'utilise cette technique pour presque tous nos projets et cela élimine beaucoup de répétitions.

30
Joshua Davis

Il y a trois ans J'ai recommandé d'utiliser la version 99, mais je viens de trouver un meilleur moyen, surtout depuis que la version 99 est hors ligne:

Dans le POM parent de votre projet, utilisez maven -forcer-plugin pour faire échouer la construction si la dépendance indésirable s'insinue dans la construction. Cela peut être fait en utilisant la règle du plugin dépendances interdites :

<plugin>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.0.1</version>
    <executions>
        <execution>
            <id>only-junit-dep-is-used</id>
            <goals>
                <goal>enforce</goal>
            </goals>
            <configuration>
                <rules>
                    <bannedDependencies>
                        <excludes>
                            <exclude>junit:junit</exclude>
                        </excludes>
                    </bannedDependencies>
                </rules>
            </configuration>
        </execution>
    </executions>
</plugin>

Puis, lorsque cela vous avertit d'une dépendance non souhaitée, excluez-la dans la section <dependencyManagement> du POM parent:

<dependency>
    <groupId>org.springframework.batch</groupId>
    <artifactId>spring-batch-test</artifactId>
    <version>2.1.8.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </exclusion>
    </exclusions>
</dependency>

De cette façon, la dépendance indésirable n’apparaîtra pas accidentellement (contrairement à un <exclusion> qui est facile à oublier), elle ne sera pas disponible même pendant la compilation (contrairement à provided scope), il n’existe dépendances fausses (contrairement à la version 99) et cela fonctionnera sans référentiel personnalisé (contrairement à la version 99). Cette approche fonctionnera même en fonction de la version de l'artefact, des classificateurs, de la portée ou de tout un groupId - voir la documentation pour plus de détails.

22
Esko Luontola

J'utilise la solution suivante: au lieu d'essayer d'exclure l'artefact dans toutes les dépendances appropriées, je dessine la dépendance comme "fournie" au niveau supérieur. Par exemple, pour éviter l'envoi xml-apis "quelle que soit la version":

    <dependency>
        <groupId>xml-apis</groupId>
        <artifactId>xml-apis</artifactId>
        <version>[1.0,]</version>
        <scope>provided</scope>
    </dependency>
10

Actuellement, il n'existe aucun moyen d'exclure plus d'une dépendance transitive à la fois, mais une demande de fonctionnalité à ce sujet est proposée sur le site Maven JIRA:

https://issues.Apache.org/jira/browse/MNG-2315

9
Peter

si vous avez besoin d'exclure toutes les dépendances transitives d'un artefact de dépendance que vous allez inclure dans un assembly, vous pouvez le spécifier dans le descripteur du plug-in Assembly:

<Assembly>
    <id>myApp</id>
    <formats>
        <format>Zip</format>
    </formats>
    <dependencySets>
        <dependencySet>
            <useTransitiveDependencies>false</useTransitiveDependencies>
            <includes><include>*:struts2-spring-plugin:jar:2.1.6</include></includes>
        </dependencySet>
    </dependencySets>
</Assembly>
6
Superole

Il existe une solution de contournement pour cela. Si vous définissez la portée d'une dépendance sur à l'exécution , les dépendances transitives seront exclues. Sachez toutefois que cela signifie que vous devez ajouter un traitement supplémentaire si vous souhaitez conditionner la dépendance à l'exécution.

Pour inclure la dépendance à l'exécution dans n'importe quel package, vous pouvez utiliser l'objectif de copie de maven-dependency-plugin pour un artefact spécifique .

6
Rich Seller

Si vous développez sous Eclipse, vous pouvez dans le graphique de dépendance de l'éditeur POM (onglets avancés activés) rechercher la dépendance que vous souhaitez exclure de votre projet, puis:

faites un clic droit dessus -> "Exclure Maven Artifact ..." et Eclipse fera l’exclusion pour vous sans avoir besoin de savoir à quelle dépendance la bibliothèque est liée.

3
Tib

Quelle est votre raison d'exclure toutes les dépendances transitives?

S'il existe un artefact particulier (tel que commons-logging) que vous devez exclure de chaque dépendance, l'approche la version 99 n'existe pas peut être utile.


Mise à jour 2012: N'utilisez pas cette approche. Utilisez maven -forcer-plugin et exclusions . La version 99 génère de fausses dépendances et le référentiel de la version 99 est hors ligne (il existe miroirs similaires mais vous ne pouvez pas compter sur eux pour rester en ligne indéfiniment non plus; il est préférable d'utiliser uniquement Maven Central).

2
Esko Luontola

Dans un numéro similaire, la dépendance souhaitée a été déclarée avec la portée fournie. Avec cette approche, les dépendances transitives sont récupérées mais ne sont PAS incluses dans la phase de package, qui correspond à vos souhaits. J'aime aussi cette solution en termes de maintenance, car il n'y a pas de pom, ni de pom personnalisé comme dans la solution de Whaley, nécessaires à la maintenance; vous devez seulement fournir la dépendance spécifique dans le conteneur et le faire

1
nkr1pt