Escludere tutte le dipendenze transitive di una singola dipendenza


221

In Maven2, per escludere una singola dipendenza transitiva, devo fare qualcosa del genere:

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

Il problema con questo approccio è che devo farlo per ogni dipendenza transitiva fornita da sample-artifactB.

Esiste un modo per utilizzare una sorta di carattere jolly per escludere tutte le dipendenze transitive contemporaneamente anziché una per una?


A volte è necessario utilizzare una versione più recente della libreria, ad esempio Spring 2.5.6, ma alcune altre dipendenze includono una versione precedente, ad esempio struts2-spring-plugin (2.1.6) include Spring 2.5.3. In tali scenari esiste un requisito per l'esclusione o l'override della versione.
Vinod Singh,

1
Usa l'edera. Stavo solo scherzando.
Jake Toronto,

Risposte:


54

Per maven2 non c'è modo di fare ciò che descrivi. Per Maven 3, c'è. Se stai usando Maven 3, vedi un'altra risposta a questa domanda

Per maven 2 consiglierei di creare il tuo pom personalizzato per la dipendenza che ha le tue <esclusioni>. Per i progetti che devono utilizzare tale dipendenza, imposta la dipendenza sul tuo pom personalizzato invece del manufatto tipico. Sebbene ciò non ti consenta necessariamente di escludere tutte le dipendenze transitive con una singola <esclusione>, ti consente di scrivere la tua dipendenza solo una volta e tutti i tuoi progetti non devono mantenere elenchi di esclusione lunghi e non necessari.


12
Consiglierei di non creare il tuo pom per aggirare le esclusioni. Questo rende la tua build molto meno portatile e riduce la comprensione.
Brian Fox,

1
Nel caso in cui non guardi oltre la risposta accettata: jira.codehaus.org/browse/MNG-3832
Jakub Bochenski

@JakubBochenski la risposta che ho dato è specifica per Maven 2, che è ciò con cui questa domanda è taggata (al momento in cui ho scritto questo commento). Il tuo link è rilevante solo per Maven 3. Indipendentemente da ciò, ho modificato la mia risposta per collegarla al link alla risposta più votata.
Whaley,

306

Ciò che ha funzionato per me (potrebbe essere una nuova funzionalità di Maven) è semplicemente fare caratteri jolly nell'elemento di esclusione.

Ho un progetto multi-modulo che contiene un modulo "app" a cui si fa riferimento in due moduli confezionati con WAR. Uno di quei moduli confezionati con WAR ha davvero bisogno solo delle classi di dominio (e non le ho ancora separate dal modulo dell'app). Ho trovato che questo funziona:

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

Il carattere jolly su groupId e artefactId esclude tutte le dipendenze che normalmente si propagano al modulo utilizzando questa dipendenza.


9
Il jolly * per gruppo e artefatto sembra funzionare in Maven 3
nkr1pt

22
Non so come sei riuscito a trovarlo funzionante, poiché Maven 3 avverte esplicitamente dell'uso dell'asterisco: [WARNING] 'dependencies.dependency.exclusions.exclusion.groupId' per <artifcat_id> con valore "*" non corrisponde a un modello ID valido. [ATTENZIONE] Si consiglia vivamente di risolvere questi problemi perché minacciano la stabilità della build. [AVVISO] Per questo motivo, le future versioni di Maven potrebbero non supportare più la costruzione di progetti così malformati Ti dispiacerebbe fornire alcune prove del fatto che è supportato e che può essere utilizzato? Altrimenti considererei il tuo commento estremamente fuorviante.
ᄂ ᄀ

7
Ha funzionato magnificamente con Maven 3.0.4. Grazie mille !
Evgeny Goldin,

1
maven 3.0.4 -> non ha funzionato bene per me. il jar risultante è molto diverso quando uso asterix o quando escludo esplicitamente tutte le dipendenze dirette. potrebbe avere a che fare con il fatto che sto usando maven-assembly-plugin per creare un grosso vaso. in questo caso, la lozione suggerita non funziona!
Gilad Hoch,

31
Questo metodo è valido Risolvono
Ryan

32

Una cosa che ho trovato utile:

Se si inserisce la dipendenza con le esclusioni nella sezione dependencyManagement della POM principale per il proprio progetto o in una POM di gestione delle dipendenze impraticabile, non è necessario ripetere l'esclusione (o la versione).

Ad esempio, se il POM principale ha:

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

Quindi i moduli nel tuo progetto possono semplicemente dichiarare la dipendenza come:

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

Il POM principale specificherà sia la versione che le esclusioni. Uso questa tecnica per quasi tutti i nostri progetti ed elimina molte ripetizioni.


23

Tre anni fa ho consigliato di utilizzare la versione 99 non esiste, ma ora ho trovato un modo migliore, soprattutto perché la versione 99 non è in linea:

Nella POM principale del tuo progetto, usa maven-enforcer-plugin per fallire la compilazione se la dipendenza indesiderata si insinua nella compilazione. Questo può essere fatto usando la regola delle dipendenze vietate del plugin :

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

Quindi, quando ti avvisa di una dipendenza indesiderata, escludila nella <dependencyManagement>sezione POM principale :

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

In questo modo la dipendenza indesiderata non verrà visualizzata accidentalmente (a differenza di una <exclusion>che è facile da dimenticare), non sarà disponibile anche durante il tempo di compilazione (a differenza provideddell'ambito), non ci sono dipendenze false (a differenza della versione 99) ed è ' Funzionerà senza un repository personalizzato (a differenza della versione 99). Questo approccio funzionerà anche in base alla versione del manufatto, ai classificatori, all'ambito o all'intero ID del gruppo - vedere la documentazione per i dettagli.


Si noti che almeno in Maven 3.1, <configuration>viene ignorato quando si esegue l'obiettivo dalla riga di comando e deve essere spostato direttamente sotto <plugin>.
David Harkness,

Ho appena trovato quello che sembra un brutto bug di Maven - versione 3.5.2. Ho un progetto con sottomoduli in cui escludo una dipendenza nella <dependencyManagement>sezione dei genitori . L'esecuzione di un mvn dependency:treeprogetto specifico non comporta affatto la dipendenza esclusa. Ma tutti i progetti che importano quella dipendenza non onoreranno <exclusions>l'altro padre del progetto, l'esclusivo si insinuerà !!! Ho dovuto passare direttamente <exclusions>a ciascun modulo pom.
cbaldan,

11

Uso la seguente soluzione alternativa: invece di provare a escludere l'artefatto in tutte le dipendenze appropriate, disegno la dipendenza come "fornita" al livello più alto. Ad esempio, per evitare di inviare xml-apis "qualunque versione":

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


6

Esiste una soluzione alternativa per questo, se si imposta l'ambito di una dipendenza su runtime , le dipendenze transitive verranno escluse. Tuttavia, tenere presente che ciò significa che è necessario aggiungere ulteriore elaborazione se si desidera impacchettare la dipendenza del runtime.

Per includere la dipendenza di runtime in qualsiasi pacchetto, è possibile utilizzare l' obiettivo di copia del plug-in maven-dependency per un artefatto specifico .


1
Questo mi ha aiutato a risolvere i problemi con il compilatore Android Dalvik che non era in grado di gestire alcune delle inclusioni transitive a due livelli --- ma ho dovuto usare <scope>provided</scope>invece di <scope>runtime</scope>.
Garret Wilson,

6

se è necessario escludere tutte le dipendenze transitive da un artefatto di dipendenza che si intende includere in un assembly, è possibile specificarlo nel descrittore per il 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>

3

Se si sviluppa in Eclipse, nel grafico delle dipendenze dell'editor POM (schede avanzate abilitate) è possibile cercare la dipendenza che si desidera escludere dal progetto e quindi:

fai clic destro su di esso -> "Escludi Maven Artefatto ..." ed Eclipse farà l'esclusione per te senza la necessità di scoprire su quale dipendenza è collegata la lib.


nota che questo funziona solo se stai usando il plugin m2eclipse
Nicolas Mommaerts,

2

Qual è la tua ragione per escludere tutte le dipendenze transitive?

Se esiste un artefatto particolare (come la registrazione comune) che è necessario escludere da ogni dipendenza, l' approccio Versione 99 non esiste potrebbe essere d'aiuto.


Aggiornamento 2012: non utilizzare questo approccio. Usa maven-enforcer-plugin ed esclusioni . La versione 99 produce dipendenze fasulle e il repository della versione 99 non è in linea (ci sono mirror simili ma non puoi fare affidamento su di essi per rimanere online per sempre; è meglio usare solo Maven Central).


1

In un problema simile avevo dichiarato la dipendenza desiderata con l'ambito fornito. Con questo approccio le dipendenze transitive vengono recuperate ma NON sono incluse nella fase del pacchetto, che è ciò che si desidera. Mi piace anche questa soluzione in termini di manutenzione, perché non ci sono pom o pom personalizzati come nella soluzione di Whaley, necessari per la manutenzione; devi solo fornire la dipendenza specifica nel contenitore ed essere fatto


-2

Usa l'ultima maven nel tuo percorso di classe .. Rimuoverà i manufatti duplicati e manterrà l'ultimo manufatto di maven ..

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.