Ako vyriešiť kolíziu verzií artefaktov v Mavene
1. Prehľad
Viacmodulové projekty Maven môžu mať zložité grafy závislostí. Tieto môžu mať neobvyklé výsledky, tým viac moduly navzájom importujú.
V tomto návode uvidíme, ako na to vyriešiť kolíziu verzií artefaktov v Mavene.
Začneme projektom s viacerými modulmi, kde sme zámerne použili rôzne verzie toho istého artefaktu. Potom uvidíme, ako zabrániť získaniu nesprávnej verzie artefaktu pomocou správy vylúčenia alebo závislostí.
Nakoniec skúsime použiť maven-enforcer-plugin aby sme uľahčili ovládanie vecí zákazom používania tranzitívnych závislostí.
2. Verzia Kolízia artefaktov
Každá závislosť, ktorú zahrnieme do nášho projektu, sa môže prepojiť s inými artefaktmi. Maven môže automaticky priniesť tieto artefakty, ktoré sa tiež nazývajú tranzitívne závislosti. Ku kolízii verzie dôjde, keď sa na ten istý artefakt odkazuje viac závislostí, ale používajú sa rôzne verzie.
V dôsledku toho sa môžu v našich aplikáciách vyskytnúť chyby vo fáze kompilácie, ako aj za behu programu.
2.1. Štruktúra projektu
Definujme viacmodulovú štruktúru projektu, s ktorou budeme experimentovať. Náš projekt sa skladá z a verzia-kolízia modul pre rodičov a tri deti:
version-collision project-a project-b project-collision
The pom.xml pre projekt-a a projekt-b sú takmer identické. Jediný rozdiel je vo verzii com.google.guava artefakt, od ktorého závisia. Najmä projekt-a používa verziu 22.0:
com.google.guava guava 22.0
Ale, projekt-b používa novšiu verziu, 29,0-jre:
com.google.guava guava 29.0-jre
Tretí modul, kolízia projektu, závisí od ďalších dvoch:
com.baeldung project-a 0.0.1-SNAPSHOT com.baeldung project-b 0.0.1-SNAPSHOT
Takže, ktorá verzia guava bude k dispozícii pre kolízia projektu?
2.2. Používanie funkcií z konkrétnej verzie závislosti
To, ktorá závislosť sa používa, môžeme zistiť vytvorením jednoduchého testu v kolízia projektu modul, ktorý používa Futures.immediateVoidFuture metóda z guava:
@Test public void whenVersionCollisionDoesNotExist_thenShouldCompile () {assertThat (Futures.immediateVoidFuture (), notNullValue ()); }
Táto metóda je k dispozícii iba od spoločnosti 29,0-jre verzia. Toto sme zdedili z jedného z ďalších modulov, ale náš kód môžeme zostaviť, iba ak dostaneme tranzitívnu závislosť od projekt-b.
2.3. Chyba kompilácie spôsobená kolíziou verzie
Podľa poradia závislostí v kolízia projektu modul v určitých kombináciách vráti Maven chybu kompilácie:
[CHYBA] Nepodarilo sa uskutočniť cieľ org.apache.maven.plugins: maven-compiler-plugin: 3.8.1: testCompile (default-testCompile) pri kolízii projektu: Zlyhanie kompilácie [CHYBA] / tutoriály / maven-all / verzia -collision / project-collision / src / test / java / com / baeldung / version / collision / VersionCollisionUnitTest.java: [12,27] nemôže nájsť symbol [ERROR] symbol: method google.common.util.concurrent.Futures
To je výsledok kolízie verzie com.google.guava artefakt. V predvolenom nastavení vyberie Maven prvú knižnicu, ktorú nájde, pre závislosti na rovnakej úrovni v strome závislostí. V našom prípade oboje com.google.guava závislosti sú v rovnakej výške a je vybraná staršia verzia.
2.4. Použitím maven-dependency-plugin
The maven-dependency-plugin je veľmi užitočný nástroj na predstavenie všetkých závislostí a ich verzií:
% závislosť mvn: strom -Dverbose [INFO] --- plugin pre závislosť maven: 2,8: strom (predvolené-cli) @ kolízia projektu --- [INFO] com.baeldung: kolízia projektu: jar: 0,0.1 -SNAPSHOT [INFO] + - com.baeldung: project-a: jar: 0.0.1-SNAPSHOT: kompilácia [INFO] | \ - com.google.guava: guava: jar: 22.0: kompilácia [INFO] \ - com.baeldung: project-b: jar: 0.0.1-SNAPSHOT: kompilácia [INFO] \ - (com.google.guava: guava : jar: 29.0-jre: kompilácia - vynechané pre konflikt s 22.0)
The -Dverbose príznak zobrazuje konfliktné artefakty. V skutočnosti máme a com.google.guava závislosť v dvoch verziách: 22.0 a 29.0-jre. Posledný z nich by sme chceli použiť v kolízia projektu modul.
3. Vylúčenie prechodnej závislosti z artefaktu
Jedným zo spôsobov riešenia kolízie verzie je odstránenie konfliktnej prechodnej závislosti od konkrétnych artefaktov. V našom príklade nechceme mať com.google.guava knižnica prechodne pridaná z projekt-a artefakt.
Preto to môžeme vylúčiť v kolízia projektu pom:
com.baeldung project-a 0.0.1-SNAPSHOT com.google.guava guava com.baeldung project-b 0.0.1-SNAPSHOT
Teraz, keď spustíme závislosť: strom príkaz, vidíme, že tam už nie je:
% závislosť mvn: strom -Dverbose [INFO] --- plugin pre závislosť maven: 2,8: strom (predvolené-cli) @ kolízia projektu --- [INFO] com.baeldung: kolízia projektu: jar: 0,0.1 -SNAPSHOT [INFO] \ - com.baeldung: project-b: jar: 0.0.1-SNAPSHOT: kompilovať [INFO] \ - com.google.guava: guava: jar: 29.0-jre: kompilácia
Výsledkom je, že fáza kompilácie končí bez chyby a môžeme použiť triedy a metódy z verzie 29,0-jre.
4. Pomocou dependencyManagement Oddiel
Maven dependencyManagement oddiel je a mechanizmus centralizácie informácií o závislosti. Jednou z najužitočnejších funkcií je ovládanie verzií artefaktov používaných ako tranzitívne závislosti.
S ohľadom na to vytvorme a dependencyManagement konfigurácia v našom rodičovi pom:
com.google.guava guava 29.0-jre
Výsledkom bude, že Maven zaistí použitie verzie 29,0-jre z com.google.guava artefakt vo všetkých podradených moduloch:
% závislosť mvn: strom -Dverbose [INFO] --- plugin pre závislosť maven: 2,8: strom (predvolené-cli) @ kolízia projektu --- [INFO] com.baeldung: kolízia projektu: jar: 0,0.1 -SNAPSHOT [INFO] + - com.baeldung: project-a: jar: 0.0.1-SNAPSHOT: kompilácia [INFO] | \ - com.google.guava: guava: jar: 29.0-jre: kompilácia (verzia spravovaná od 22.0) [INFO] \ - com.baeldung: project-b: jar: 0.0.1-SNAPSHOT: kompilácia [INFO] \ - (com.google.guava: guava: jar: 29.0-jre: kompilácia - verzia spravovaná od 22.0; pre duplikát vynechaná)
5. Zabráňte náhodným tranzitným závislostiam
The maven-enforcer-plugin poskytuje mnoho zabudovaných pravidiel, ktoré zjednodušiť správu viacmodulového projektu. Jeden z nich zakazuje používanie tried a metód z tranzitívnych závislostí.
Explicitná deklarácia závislosti odstraňuje možnosť kolízie verzií artefaktov. Pridajme maven-enforcer-plugin s týmto pravidlom nášmu rodičovi pom:
org.apache.maven.plugins maven-enforcer-plugin 3.0.0-M3 vynútiť-zakázať-závislosti vynútiť
V dôsledku toho musíme teraz výslovne vyhlásiť com.google.guava artefakt v našom kolízia projektu modul, ak ho chceme používať sami. Musíme buď určiť verziu, ktorá sa má použiť, alebo nastaviť dependencyManagement u rodiča pom.xml. Vďaka tomu je náš projekt viac odolný voči chybám, ale vyžaduje si od nás, aby sme boli v našom dokumente explicitnejší pom.xml súbory.
6. Záver
V tomto článku sme videli, ako vyriešiť kolíziu verzií artefaktov v Mavene.
Najskôr sme preskúmali príklad kolízie verzie v multimodulovom projekte.
Potom sme si ukázali, ako vylúčiť prechodné závislosti v pom.xml. Pozreli sme sa na to, ako ovládať verzie závislostí pomocou dependencyManagement oddiel v rodič pom.xml.
Nakoniec sme vyskúšali maven-enforcer-plugin zakázať používanie tranzitívnych závislostí s cieľom prinútiť každý modul prevziať kontrolu nad svojou vlastnou.
Ako vždy, kód zobrazený v tomto článku je k dispozícii na GitHub.