2010-10-14 15 views
74

Ecco il mio problema generico:Maven: come superare la dipendenza dalle aggiunto di una biblioteca

Il mio progetto P dipende da una che dipende B che dipende C che dipende dalla versione 1.0.1 di D.

C'è un problema con la versione 1.0.1 di D e voglio forzare l'uso di un altro modulo. Non so come dichiararlo nelle POM del mio progetto poiché non ho aggiunto direttamente una dipendenza su D. È C che ha dichiarato la dipendenza su D.

Importante: in questo caso, non viene modificata solo la versione, ma anche il gruppo & artefatto. Quindi non si tratta solo di sovrascrivere la versione della dipendenza, ma piuttosto di escludere un modulo e includerne un altro.

Nel caso concreto, D è StAX il cui 1.0.1 ha un bug. Secondo le note nel bug, "i problemi sono stati risolti sostituendo stax-api-1.0.1 (maven GroupId = stax) da stax-api-1.0-2 (maven GroupId = javax.xml.stream)" quindi I sto provando proprio questo.

Così, D = Stax: Stax-api: jar: 1.0.1 e C = org.apache.xmlbeans: XMLBeans: vaso: 2.3.0

Sto utilizzando Maven 2.0.9 nel caso questioni.

uscita di mvn dipendenza: Albero"

mvn dependency:tree 
[..snip..] 
[INFO] +- org.apache.poi:poi-ooxml:jar:3.6:compile 
[INFO] | +- org.apache.poi:poi-ooxml-schemas:jar:3.6:compile 
[INFO] | | +- org.apache.xmlbeans:xmlbeans:jar:2.3.0:compile 
[INFO] | | | \- stax:stax-api:jar:1.0.1:compile 

In POM del mio progetto ho il seguente dipendenza da "A":.

<dependency> 
    <groupId>org.apache.poi</groupId> 
    <artifactId>poi</artifactId> 
    <version>3.6</version> 
</dependency> 
<dependency> 
    <groupId>org.apache.poi</groupId> 
    <artifactId>poi-ooxml</artifactId> 
    <version>3.6</version> 
</dependency> 

Grazie in anticipo

risposta

69

specificare semplicemente il versione nel tuo attuale pom. La versione specificata qui sostituirà altre

Forzare una versione
Una versione sarà sempre onorato se viene dichiarata nel POM corrente con una versione particolare - tuttavia, va notato che questo sarà anche influenzare altri pon a valle se essa stessa è dipendeva utilizzando transitiva dipendenze.


Risorse:

+3

non è chiaro come posso specificare la versione poiché non dichiaro una dipendenza su D. Inoltre, il primo collegamento fornito ha "Questo documento descrive il resto dei requisiti per la gestione delle dipendenze che NON sono ancora stati implementati per Maven 2.0, in particolare per quanto riguarda le dipendenze transitive. " in cima. – wishihadabettername

+0

@wishihadabettername, come detto nell'altro documento: "È possibile aggiungere esplicitamente una dipendenza a D 2.0 in A per forzare l'utilizzo di D 2.0" –

+1

In realtà si duplica la stessa voce nel proprio pom. Nella tua dipendenza, specifica uno che desideri. Ciò sostituirà qualsiasi versione utilizzata dalle dipendenze "più profonde". –

16

In alternativa, si può solo escludere la dipendenza che non si desidera. STAX è incluso in JDK 1.6, quindi se stai usando 1.6 puoi solo escluderlo del tutto.

Il mio esempio qui sotto è leggermente sbagliato per te - hai solo bisogno di una delle due esclusioni ma non sono abbastanza sicuro di quale. Esistono altre versioni di Stax che fluttuano, nel mio esempio qui sotto importavo A che importava B che importava C & D che ciascuna (attraverso ancora più dipendenze transitive) importava versioni differenti di Stax. Quindi, nella mia dipendenza da "A", ho escluso entrambe le versioni di Stax.

<dependency> 
    <groupId>a.group</groupId> 
    <artifactId>a.artifact</artifactId> 
    <version>a.version</version> 
    <exclusions> 
    <!-- STAX comes with Java 1.6 --> 
    <exclusion> 
     <artifactId>stax-api</artifactId> 
     <groupId>javax.xml.stream</groupId> 
    </exclusion> 
    <exclusion> 
     <artifactId>stax-api</artifactId> 
     <groupId>stax</groupId> 
    </exclusion> 
    </exclusions> 
<dependency> 
+0

E 'necessario notare che questa dipendenza transitiva può essere usata ed esclusa può causare un errore di compilazione se è necessario. –

+0

Se si utilizza un JDK moderno (ovvero la versione 1.6+) e si ha bisogno della versione molto vecchia di stax inclusa tramite una dipendenza transitiva, è probabile che si verificheranno tutti i tipi di terribili problemi del caricatore di classi di runtime. Il mio consiglio: usa quello nel JDK. Se si ottiene un "errore di build" si sta facendo affidamento su un'API antica di un modulo che dovrebbe essere aggiornato. Oppure: ripristina il tuo JDK a 1.5. Buona fortuna. – scot

3

Ho anche avuto problemi a superare una dipendenza in una libreria di terze parti. Ho usato l'approccio di scot con l'esclusione, ma ho anche aggiunto la dipendenza con la versione più recente nel pom. (Io ho usato Maven 3.3.3)

Così, per esempio, la Stax sarebbe simile a questa:

<dependency> 
    <groupId>a.group</groupId> 
    <artifactId>a.artifact</artifactId> 
    <version>a.version</version> 
    <exclusions> 
    <!-- STAX comes with Java 1.6 --> 
    <exclusion> 
     <artifactId>stax-api</artifactId> 
     <groupId>javax.xml.stream</groupId> 
    </exclusion> 
    <exclusion> 
     <artifactId>stax-api</artifactId> 
     <groupId>stax</groupId> 
    </exclusion> 
    </exclusions> 
<dependency> 

<dependency> 
    <groupId>javax.xml.stream</groupId> 
    <artifactId>stax-api</artifactId> 
    <version>1.0-2</version> 
</dependency> 
0

Ciò che si mette dentro la </dependencies> tag del pom radice sarà incluso da tutti i moduli del bambino pom pom. Se tutti i tuoi moduli usano questa dipendenza, questa è la strada da percorrere.

Tuttavia, se solo 3 su 10 dei moduli figlio utilizzano una dipendenza, non si desidera includere questa dipendenza in tutti i moduli figlio. In tal caso, puoi semplicemente inserire la dipendenza all'interno di </dependencyManagement>. Ciò assicurerà che qualsiasi modulo figlio che ha bisogno della dipendenza lo dichiari nel proprio file pom, ma useranno la stessa versione di quella dipendenza specificata nel tag </dependencyManagement>.

È inoltre possibile utilizzare </dependencyManagement> per modificare la versione utilizzata nelle dipendenze transitive, poiché la versione dichiarata nel file pom più in alto è quella che verrà utilizzata. Questo può essere utile se il progetto A include un progetto esterno B v1.0 che include un altro progetto esterno C v1.0. A volte capita che una violazione della sicurezza si trovi nel progetto C v1.0 che è corretto in v1.1, ma gli sviluppatori di B sono lenti ad aggiornare il proprio progetto per utilizzare la versione 1.1 di C. In questo caso, si può semplicemente dichiarare una dipendenza da C v1.1 nella root pom del progetto dentro `, e tutto andrà bene (supponendo che B v1.0 sarà ancora in grado di compilare con C v1.1).

Problemi correlati