Maven: come sovrascrivere la dipendenza aggiunta da una libreria


116

Ecco il mio problema generico:

Il mio progetto P dipende da A che dipende da B che dipende da 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 nei POM del mio progetto poiché non ho aggiunto direttamente una dipendenza da D. È C che ha dichiarato la dipendenza da D.

Importante: in questo caso, non viene modificata solo la versione, ma anche il gruppo e l'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 la 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) con stax-api-1.0-2 (maven GroupId = javax.xml.stream)" quindi ho Sto provando proprio questo.

Quindi, D = stax: stax-api: jar: 1.0.1 e C = org.apache.xmlbeans: xmlbeans: jar: 2.3.0

Sto usando Maven 2.0.9 nel caso sia importante.

Output della dipendenza mvn: 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

Nel POM del mio progetto ho la 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.

Risposte:


100

Basta specificare la versione nel tuo attuale pom. La versione specificata qui sovrascriverà l'altra.

Forzare una versione
Una versione sarà sempre rispettata se è dichiarata nel POM corrente con una particolare versione - tuttavia, va notato che questo influenzerà anche altri poms a valle se essa stessa dipende dall'uso di dipendenze transitive.


Risorse:


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

@wishihadabettername, Come detto nell'altro documento: "Potresti aggiungere esplicitamente una dipendenza a D 2.0 in A per forzare l'uso di D 2.0"
Colin Hebert

1
In realtà duplichi la stessa voce <dipendenza> nel tuo pom. Nella tua dipendenza, specifica una <versione> che desideri. Ciò sovrascriverà qualsiasi versione utilizzata da dipendenze "più profonde".
Keith Tyler

27

In alternativa, puoi semplicemente escludere la dipendenza che non desideri. STAX è incluso in JDK 1.6, quindi se stai usando 1.6 puoi semplicemente escluderlo completamente.

Il mio esempio qui sotto è leggermente sbagliato per te: hai solo bisogno di una delle due esclusioni ma non sono abbastanza sicuro di quale. Ci sono altre versioni di Stax fluttuanti, nel mio esempio qui sotto stavo importando A che importava B che importava C & D che ciascuno (attraverso dipendenze ancora più 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>

1
È necessario notare che questa dipendenza transitiva può essere utilizzata e l'esclusione può causare un errore di compilazione se necessario.
Bernhard Colby

Se stai usando un JDK moderno (cioè 1.6+) e hai bisogno della versione molto più vecchia di stax inclusa tramite una dipendenza transitiva, probabilmente ti imbatterai in tutti i tipi di terribili problemi di caricamento classi di runtime. Il mio consiglio: usa quello nel JDK. Se si verifica un "errore di compilazione", si fa affidamento su un'antica API di qualche forma che dovrebbe essere aggiornata. Oppure: ripristina il tuo JDK a 1.5. Buona fortuna.
scozzese

11

Quello che metti all'interno del </dependencies>tag della radice pom sarà incluso da tutti i moduli figlio della radice pom. Se tutti i tuoi moduli usano quella dipendenza, questa è la strada da percorrere.

Tuttavia, se solo 3 su 10 dei tuoi moduli figlio usano una certa dipendenza, non vuoi che questa dipendenza sia inclusa in tutti i tuoi moduli figlio. In tal caso, puoi semplicemente inserire la dipendenza all'interno del file </dependencyManagement>. Ciò assicurerà che qualsiasi modulo figlio che necessita della dipendenza debba dichiararlo nel proprio file pom, ma utilizzerà la stessa versione di quella dipendenza specificata nel </dependencyManagement>tag.

Puoi anche usare il </dependencyManagement>per modificare la versione utilizzata nelle dipendenze transitive, perché la versione dichiarata nel file pom più in alto è quella che verrà utilizzata. Ciò 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 viene corretta nella v1.1, ma gli sviluppatori di B sono lenti ad aggiornare il loro progetto per utilizzare la v1.1 di C.In tal caso, puoi semplicemente dichiarare una dipendenza da C v1.1 nella root pom del progetto all'interno di `, e tutto andrà bene (supponendo che B v1.0 sarà ancora in grado di compilare con C v1.1).


10

Ho anche avuto problemi a ignorare 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. (Ho usato Maven 3.3.3)

Quindi, per l'esempio stAX, sarebbe simile a questo:

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

1

La risposta accettata è corretta ma vorrei aggiungere i miei due centesimi. Ho riscontrato un problema in cui avevo un progetto A che aveva un progetto B come dipendenza. Entrambi i progetti usano slf4j ma il progetto B usa log4j mentre il progetto A usa logback. Il progetto B usa slf4j 1.6.1, mentre il progetto A usa slf4j 1.7.5 (a causa della dipendenza 1.2.3 di logback già inclusa).

Il problema: il progetto A non è riuscito a trovare una funzione che esiste su slf4j 1.7.5, dopo aver controllato la scheda della gerarchia delle dipendenze di eclipe ho scoperto che durante la compilazione stava usando slf4j 1.6.1 dal progetto B, invece di usare slf4j 1.7.5 di logback .

Ho risolto il problema modificando l'ordine delle dipendenze dal progetto A pom, quando ho spostato la voce del progetto B sotto la voce di logback, maven ha iniziato a creare il progetto usando slf4j 1.7.5.

Modifica: aggiunta della dipendenza slf4j 1.7.5 prima che funzionasse anche la dipendenza del progetto B.

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.