Existe-t-il un moyen d'exclure une dépendance Maven globalement?

93

J'essaie de trouver un moyen «générique» d'exclure une dépendance transitive de l'inclusion sans avoir à l'exclure de toutes les dépendances qui en dépendent. Par exemple, si je veux exclure slf4j, je fais ce qui suit:

  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jmx</artifactId>
    <version>3.3.2.GA</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>3.4.0.GA</version>
    <type>jar</type>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

C'est en partie pour nettoyer le fichier pom, en partie pour éviter des problèmes à l'avenir avec des personnes ajoutant des dépendances qui dépendent de cette dépendance exclue - et oubliant de l'exclure.

Y a-t-il un moyen?

Sébastien Le Callonnec
la source
2
Ne résout pas le problème, mais maven-enforcer-plugin a une fonctionnalité de dépendances interdites qui échouera la construction si des dépendances indésirables se faufilent. Vous devez toujours les exclure manuellement, cependant: - /
dnault
Une réponse alternative est disponible ici: stackoverflow.com/a/39979760/363573
Stephan

Réponses:

69

est-ce que cela aide? http://jlorenzen.blogspot.com/2009/06/maven-global-excludes.html

"En supposant que je veuille exclure avalon-framework de mon WAR, j'ajouterais ce qui suit à mes projets POM avec une portée de fourni. Cela fonctionne sur toutes les dépendances transitives et vous permet de le spécifier une fois.

<dependencies>
  <dependency>
      <artifactId>avalon-framework</artifactId>
      <groupId>avalon-framework</groupId>
      <version>4.1.3</version>
      <scope>provided</scope>
  </dependency>
</dependencies>

Cela fonctionne même lorsque vous le spécifiez dans le POM parent, ce qui empêcherait les projets d'avoir à le déclarer dans tous les POM enfants. "

Joffer
la source
49
Ce n'est toujours qu'un hack partiel - la dépendance ne se retrouvera pas dans l'artefact de construction mais elle est toujours disponible pendant les tests.
Tuukka Mustonen
@TuukkaMustonen Qu'en est-il de la runtimeportée au lieu de la providedportée?
Stephan
Que se passe-t-il si avalon-framework 4.1.3+ est inclus ailleurs dans le projet? Voir une réponse ici: stackoverflow.com/a/39979760/363573
Stephan
Je n'utilise plus Maven, donc je ne suis pas en mesure de tester les autres réponses, mais j'encourage les gens à les considérer au cas où il y en aurait une qui ne serait pas un hack partiel, selon @TuukkaMustonen
Joffer
18

J'ai créé un pot vide et créé cette dépendance:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <scope>system</scope>
    <systemPath>${basedir}/src/lib/empty.jar</systemPath>
    <version>0</version>
</dependency>

Ce n'est pas parfait car à partir de maintenant vous avez un jar vide dans votre chemin de compilation / test. Mais ce n'est que cosmétique.

Guus Bloemsma
la source
3
systemscope est désormais obsolète: maven.apache.org/guides/introduction/…
Jason Young
Pour éviter d'utiliser systemscope, consultez le référentiel virtuel Maven version99.grons.nl (Attention: HTTP uniquement) ou (pour commons-logging / log4j uniquement) voir «alternative 3) artefacts vides» ici: slf4j.org/faq.html#excludingJCL
seanf
16

Pour développer le commentaire de dnault :

On peut utiliser la règle Banned Dependencies du plugin Maven Enforcer pour s'assurer que les dépendances sont exclues. Il faut toujours les exclure manuellement, mais la construction échouera si quelqu'un ajoute la dépendance ailleurs par erreur.

<dependencies>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jmx</artifactId>
    <version>3.3.2.GA</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
</dependencies>

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.4.1</version>
    <executions>
      <execution>
        <goals>
          <goal>enforce</goal>
        </goals>
        <configuration>
          <rules>
            <bannedDependencies>
              <excludes>
                <exclude>org.slf4j:slf4j-api</exclude>
              </excludes>
            </bannedDependencies>
          </rules>
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>

Il existe également une demande de fonctionnalité ouverte: MNG-1977 Exclusions de dépendances globales

Arend contre Reinersdorff
la source
2
Suite à votre réponse et à la lecture de la discussion à partir du lien que vous avez fourni, j'ai réalisé que des pots indésirables entraient parfois dans de gros pots simplement parce que les versions de maven utilisées sur le serveur local et sur le serveur sont différentes, donc la logique d'empaquetage peut ajouter des versions assez différentes de dépendances si elles ne sont pas strictement appliquées. Pour résoudre mon problème similaire, j'ai utilisé la configuration / l'exclusion / l'exclusion de spring-boot-maven-plugin pour le <goal> reconditionnement </goal>.
après
10

Pour rappel, voici la réponse de la documentation officielle de Maven:

Pourquoi les exclusions sont faites sur une base par dépendance, plutôt qu'au niveau POM

Ceci est principalement fait pour être sûr que le graphe de dépendances est prévisible et pour empêcher les effets d'héritage d'exclure une dépendance qui ne devrait pas être exclue. Si vous arrivez à la méthode de dernier recours et devez mettre en place une exclusion, vous devez être absolument certain de laquelle de vos dépendances entraîne cette dépendance transitive indésirable.

Si l'on veut rendre une construction plus robuste, une plage de versions peut être utilisée. Cela garantirait qu'aucune version plus récente de la dépendance ne puisse interférer avec le projet.

<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>[1.4.2,)</version>
   <scope>provided</scope>
</dependency>

Toute version de slf4j-api> = 1.4.2 sera considérée comme offerte (fournie) au moment de l'exécution, soit à partir d'un chemin de classe configuré, soit d'un conteneur.

Références

Stéphan
la source