Hvordan løse en versjon Kollisjon av gjenstander i Maven

1. Oversikt

Multimodul Maven-prosjekter kan ha komplekse avhengighetsgrafer. Disse kan ha uvanlige resultater, jo mer modulene importeres fra hverandre.

I denne opplæringen vil vi se hvordan du gjør det løse versjonskollisjon av gjenstander i Maven.

Vi starter med et multimodulprosjekt der vi bevisst har brukt forskjellige versjoner av samme gjenstand. Så får vi se hvordan vi kan forhindre å få feil versjon av en gjenstand med enten ekskludering eller avhengighetsadministrasjon.

Til slutt vil vi prøve å bruke maven-enforcer-plugin for å gjøre ting lettere å kontrollere, ved å forby bruk av transitive avhengigheter.

2. Versjon kollisjon av gjenstander

Hver avhengighet som vi inkluderer i prosjektet vårt, kan knytte til andre gjenstander. Maven kan automatisk hente inn disse gjenstandene, også kalt transitive avhengigheter. Versjonskollisjon skjer når flere avhengigheter lenker til samme gjenstand, men bruker forskjellige versjoner.

Som et resultat kan det være feil i applikasjonene våre både i kompileringsfasen og også ved kjøretid.

2.1. Prosjektstruktur

La oss definere en multimodul prosjektstruktur å eksperimentere med. Prosjektet vårt består av en versjon-kollisjon foreldre- og tre barnemoduler:

versjon-kollisjonsprosjekt-et prosjekt-b prosjekt-kollisjon 

De pom.xml til prosjekt-a og prosjekt-b er nesten identiske. Den eneste forskjellen er versjonen av com.google.guava gjenstand som de er avhengige av. Spesielt, prosjekt-a bruker versjon 22.0:

  com.google.guava guava 22.0 

Men, prosjekt-b bruker den nyere versjonen, 29.0-jre:

  com.google.guava guava 29.0-jre 

Den tredje modulen, prosjekt-kollisjon, avhenger av de to andre:

  com.baeldung prosjekt-a 0.0.1-SNAPSHOT com.baeldung prosjekt-b 0.0.1-SNAPSHOT 

Så hvilken versjon av guava vil være tilgjengelig for prosjekt-kollisjon?

2.2. Bruke funksjoner fra spesifikk avhengighetsversjon

Vi kan finne ut hvilken avhengighet som brukes ved å lage en enkel test i prosjekt-kollisjon modul som bruker Futures.immediateVoidFuture metode fra guava:

@Test offentlig ugyldig nårVersionCollisionDoesNotExist_thenShouldCompile () {assertThat (Futures.immediateVoidFuture (), notNullValue ()); }

Denne metoden er bare tilgjengelig fra 29.0-jre versjon. Vi har arvet dette fra en av de andre modulene, men vi kan bare kompilere koden vår hvis vi har den transitive avhengigheten fra prosjekt-b.

2.3. Kompileringsfeil forårsaket av versjonskollisjon

Avhengig av rekkefølgen av avhengighet i prosjekt-kollisjon modul, i visse kombinasjoner returnerer Maven en kompileringsfeil:

[FEIL] Kunne ikke kjøre mål org.apache.maven.plugins: maven-compiler-plugin: 3.8.1: testCompile (standard-testCompile) på prosjektkollisjon: kompileringsfeil [FEIL] / tutorials / maven-all / version -kollisjon / prosjektkollisjon / src / test / java / com / baeldung / versjon / kollisjon / VersionCollisionUnitTest.java: [12,27] finner ikke symbol [FEIL] symbol: metode umiddelbarVoidFuture () [FEIL] plassering: klasse kom. google.common.util.concurrent.Futures

Det er resultatet av versjonens kollisjon av com.google.guava gjenstand. For avhengigheter på samme nivå i et avhengighetstre velger Maven som standard det første biblioteket det finner. I vårt tilfelle begge deler com.google.guava avhengigheter er i samme høyde, og den eldre versjonen er valgt.

2.4. Ved hjelp av maven-avhengighets-plugin

De maven-avhengighets-plugin er et veldig nyttig verktøy for å presentere alle avhengigheter og deres versjoner:

% mvn avhengighet: tre -Dverbose [INFO] --- maven-avhengighet-plugin: 2.8: tre (standard-cli) @ prosjekt-kollisjon --- [INFO] com.baeldung: prosjekt-kollisjon: jar: 0.0.1 -SNAPSHOT [INFO] + - com.baeldung: prosjekt-a: jar: 0.0.1-SNAPSHOT: kompilere [INFO] | \ - com.google.guava: guava: jar: 22.0: kompilere [INFO] \ - com.baeldung: prosjekt-b: jar: 0.0.1-SNAPSHOT: kompilere [INFO] \ - (com.google.guava: guava : jar: 29.0-jre: kompilere - utelatt for konflikt med 22.0)

De -Dverbose flagget viser motstridende gjenstander. Vi har faktisk en com.google.guava avhengighet i to versjoner: 22.0 og 29.0-jre. Sistnevnte er den vi vil bruke i prosjekt-kollisjon modul.

3. Ekskluderer en transitiv avhengighet fra en gjenstand

En måte å løse en versjonskollisjon på er fjerne en motstridende transitiv avhengighet fra spesifikke gjenstander. I vårt eksempel ønsker vi ikke å ha com.google.guava bibliotek lagt til fra biblioteket prosjekt-a gjenstand.

Derfor kan vi ekskludere det i prosjekt-kollisjon pom:

  com.baeldung prosjekt-a 0.0.1-SNAPSHOT com.google.guava guava com.baeldung prosjekt-b 0.0.1-SNAPSHOT 

Nå, når vi kjører avhengighet: tre kommando, kan vi se at den ikke er der lenger:

% mvn avhengighet: tre -Dverbose [INFO] --- maven-avhengighet-plugin: 2.8: tre (standard-cli) @ prosjekt-kollisjon --- [INFO] com.baeldung: prosjekt-kollisjon: jar: 0.0.1 -SNAPSHOT [INFO] \ - com.baeldung: project-b: jar: 0.0.1-SNAPSHOT: compile [INFO] \ - com.google.guava: guava: jar: 29.0-jre: compile

Som et resultat slutter kompileringsfasen uten feil, og vi kan bruke klassene og metodene fra versjonen 29.0-jre.

4. Bruke avhengighetLedelse Seksjon

Maven's avhengighetLedelse seksjonen er en mekanisme for sentralisering av avhengighetsinformasjon. En av de mest nyttige funksjonene er å kontrollere versjoner av gjenstander som brukes som transitive avhengigheter.

Med det i tankene, la oss lage en avhengighetLedelse konfigurasjon hos foreldrene våre pom:

   com.google.guava guava 29.0-jre 

Som et resultat vil Maven sørge for å bruke versjonen 29.0-jre av com.google.guava gjenstand i alle barnemoduler:

% mvn avhengighet: tre -Dverbose [INFO] --- maven-avhengighet-plugin: 2.8: tre (standard-cli) @ prosjekt-kollisjon --- [INFO] com.baeldung: prosjekt-kollisjon: jar: 0.0.1 -SNAPSHOT [INFO] + - com.baeldung: prosjekt-a: jar: 0.0.1-SNAPSHOT: kompilere [INFO] | \ - com.google.guava: guava: jar: 29.0-jre: kompilere (versjon administrert fra 22.0) [INFO] \ - com.baeldung: prosjekt-b: jar: 0.0.1-SNAPSHOT: kompilere [INFO] \ - (com.google.guava: guava: jar: 29.0-jre: compile - versjon administrert fra 22.0; utelatt for duplikat)

5. Forhindre utilsiktet uavhengige avhengigheter

De maven-enforcer-plugin gir mange innebygde regler som forenkle ledelsen av et multimodulprosjekt. En av dem forbyr bruken av klasser og metoder fra transitive avhengigheter.

Eksplisitt avhengighetserklæring fjerner muligheten for versjonskollisjon av gjenstander. La oss legge til maven-enforcer-plugin med den regelen til vår foreldre pom:

 org.apache.maven.plugins maven-enforcer-plugin 3.0.0-M3 håndheve-utestengt-avhengigheter håndheve 

Som en konsekvens må vi nå eksplisitt erklære com.google.guava gjenstand i vår prosjekt-kollisjon modul hvis vi ønsker å bruke den selv. Vi må enten spesifisere versjonen som skal brukes, eller sette opp avhengighetLedelse hos foreldrene pom.xml. Dette gjør prosjektet vårt mer feilsikkert, men krever at vi er mer eksplisitte i vårt pom.xml filer.

6. Konklusjon

I denne artikkelen har vi sett hvordan vi kan løse en versjonskollisjon av gjenstander i Maven.

Først utforsket vi et eksempel på en versjonskollisjon i et multimodulprosjekt.

Så viste vi hvordan man ekskluderer transitive avhengigheter i pom.xml. Vi så på hvordan du kan kontrollere avhengighetsversjoner med avhengighetLedelse seksjon i foreldrene pom.xml.

Til slutt prøvde vi maven-enforcer-plugin å forby bruk av transitive avhengigheter for å tvinge hver modul til å ta kontroll over seg selv.

Som alltid er koden vist i denne artikkelen tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found