C'è un modo per escludere una dipendenza Maven a livello globale?


92

Sto cercando di trovare un modo "generico" per escludere una dipendenza transitiva dall'inclusione senza doverla escludere da tutte le dipendenze che dipendono da essa. Ad esempio, se voglio escludere slf4j, faccio quanto segue:

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

Questo è in parte per ripulire il file pom, in parte per evitare problemi in futuro con persone che aggiungono dipendenze che dipendono da quella dipendenza esclusa e dimenticandosi di escluderla.

C'è un modo?


2
Non risolve il problema, ma maven-enforcer-plugin ha una funzione di dipendenze vietate che fallirà la compilazione se le dipendenze indesiderate si intrufolano. Devi comunque escluderle manualmente, però: - /
dnault

Una risposta alternativa è disponibile qui: stackoverflow.com/a/39979760/363573
Stephan

Risposte:


69

questo aiuta? http://jlorenzen.blogspot.com/2009/06/maven-global-excludes.html

"Supponendo che io voglia escludere avalon-framework dal mio WAR, aggiungerei quanto segue ai miei progetti POM con uno scopo fornito. Funziona con tutte le dipendenze transitive e ti permette di specificarlo una volta.

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

Funziona anche quando lo si specifica nel POM padre, il che impedirebbe ai progetti di doverlo dichiarare in tutti i POM figlio. "


49
È ancora solo un hack parziale: la dipendenza non finirà all'interno del manufatto di build ma è ancora disponibile durante i test.
Tuukka Mustonen

@TuukkaMustonen E lo runtimescopo invece dello providedscopo?
Stephan

Cosa succede se avalon-framework 4.1.3+ è incluso altrove nel progetto? Vedi una risposta qui: stackoverflow.com/a/39979760/363573
Stephan

Non uso più Maven, quindi non sono in grado di testare le altre risposte, ma incoraggerei le persone a prenderle in considerazione nel caso ce ne sia uno che non sia un hack parziale, come per @TuukkaMustonen
Joffer

18

Ho creato un jar vuoto e ho creato questa dipendenza:

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

Non è perfetto perché d'ora in poi hai un jar vuoto nel tuo percorso di compilazione / test. Ma questo è solo cosmetico.


3
systeml'ambito è ora deprecato: maven.apache.org/guides/introduction/…
Jason Young,

Per evitare di utilizzare l' systemambito, vedere il repository Maven virtuale version99.grons.nl (Avvertenza: solo HTTP) o (solo per il registro dei comuni / log4j) vedere "alternativa 3) artefatti vuoti" qui: slf4j.org/faq.html#excludingJCL
seanf

16

Per espandere il commento di dnault :

È possibile utilizzare la regola delle dipendenze vietate del plug-in Maven Enforcer per garantire che le dipendenze siano escluse. Bisogna ancora escluderli manualmente, ma la compilazione fallirà se qualcuno aggiunge per errore la dipendenza altrove.

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

Inoltre è presente una richiesta di funzionalità aperta: MNG-1977 Esclusioni di dipendenza globale


2
Seguendo la tua risposta e leggendo la discussione dal link che hai fornito, mi sono reso conto che alcuni barattoli indesiderati stanno entrando in fat jar alcune volte solo perché la versione di Maven utilizzata su locale e sul server è diversa, quindi la logica di pacchettizzazione può aggiungere versioni abbastanza diverse delle dipendenze se non vengono applicate rigorosamente. Per risolvere il mio problema simile ho usato spring-boot-maven-plugin configuration / exclude / exclude per <goal> repackage </goal>.
aprodan

10

Come promemoria, ecco la risposta dalla documentazione ufficiale di Maven:

Perché le esclusioni vengono effettuate in base alla dipendenza, piuttosto che a livello di POM

Questo viene fatto principalmente per essere sicuri che il grafico delle dipendenze sia prevedibile e per evitare che gli effetti dell'ereditarietà escludano una dipendenza che non dovrebbe essere esclusa. Se arrivi al metodo dell'ultima risorsa e devi inserire un'esclusione, dovresti essere assolutamente certo quale delle tue dipendenze sta portando quella dipendenza transitiva indesiderata.

Se si desidera rendere una build più robusta, è possibile utilizzare una gamma di versioni . Ciò garantirebbe che nessuna versione più recente della dipendenza possa interferire con il progetto.

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

Qualsiasi versione di slf4j-api> = 1.4.2 sarà considerata come offerta (fornita) in fase di esecuzione, da un classpath configurato o da un contenitore.

Riferimenti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.