Řešení konfliktů verzí závislostí

Tento článek popisuje konflikty verzí závislostí a jejich řešení.

Klientské knihovny Azure pro Javu závisí na oblíbených knihovnách třetích stran, například na následujících knihovnách:

Mnoho aplikací a architektur Java tyto knihovny používá přímo nebo tranzitivně, což vede ke konfliktům verzí. Správci závislostí, jako je Maven a Gradle , přeloží všechny závislosti tak, aby byla na cestě ke třídám pouze jedna verze každé závislosti. Není však zaručeno, že vyřešená verze závislostí je kompatibilní se všemi příjemci této závislosti ve vaší aplikaci. Další informace najdete v tématu Úvod do mechanismu závislostí v dokumentaci k Mavenu a vysvětlení řešení závislostí v dokumentaci Gradle.

Nekompatibilitu rozhraní API přímých závislostí vede k chybám kompilace. Nekompatibilitu závislostí diamantů obvykle vede k selháním modulu runtime, jako je NoClassDefFoundError, NoSuchMethodError nebo jiná chyba linkage. Ne všechny knihovny striktně dodržují sémantické správy verzí a zásadní změny se někdy dějí ve stejné hlavní verzi.

Diagnostika problémů s neshodou verzí

Následující části popisují metody diagnostiky problémů s neshodou verzí.

Použití nástroje pro sestavení Sady Azure SDK pro Javu

Nástroj pro sestavení Sady Azure SDK pro Javu, představený v tématu Začínáme se sadou Azure SDK a Apache Mavenem, pomáhá identifikovat běžně zjištěné problémy. Doporučujeme přidat tento nástroj pro sestavení do projektu a spustit ho přidáním azure:run cíle Mavenu do běžného procesu sestavení. S příslušnou konfigurací můžete identifikovat a vyřešit konflikty závislostí proaktivněji, než se stanou problémy za běhu.

Zobrazení stromu závislostí

Spusťte mvn dependency:tree nebo gradle dependencies --scan zobrazte celý strom závislostí pro vaši aplikaci s čísly verzí. mvn dependency:tree -Dverbose poskytuje více informací, ale může být zavádějící. Další informace najdete v dokumentaci k Závislostem Apache Mavenu . Pro každou knihovnu, u které se domníváte, že došlo ke konfliktu verzí, si poznamenejte číslo verze a určete, které komponenty na ní závisí.

Řešení závislostí ve vývojových a produkčních prostředích může fungovat jinak. Moduly plug-in Apache Spark, Apache Flink, Databricks a IDE vyžadují další konfiguraci pro vlastní závislosti. Můžou si také přinést vlastní verze klientských knihoven Azure nebo běžných komponent. Další informace najdete v následujících článcích:

Další informace o řešení konfliktů v takových prostředích najdete v části Vytvoření fat JAR dále v tomto článku.

Konfigurace Azure Functions

Interní verze závislostí ve službě Azure Functions (pouze v Javě 8) má přednost před verzí poskytovanou uživatelem. Tato závislost způsobuje konflikty verzí, zejména s Jacksonem, Nettym a Reactor.

Chcete-li tento problém vyřešit, nastavte proměnnou FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS prostředí na true hodnotu nebo 1. Nezapomeňte aktualizovat nástroje Azure Function Tools (v2 nebo v3) na nejnovější verzi.

Poznámka:

Tato konfigurace se vztahuje pouze na Azure Functions s Javou 8. Funkce, na kterých běží Java 11, nepotřebují speciální konfiguraci.

Konfigurace Apache Sparku

Sada Azure SDK pro Javu podporuje více verzí Jacksona, někdy ale může docházet k problémům v závislosti na nástrojích sestavení a jejich pořadí řešení závislostí. Dobrým příkladem tohoto problému je Apache Spark verze 3.0.0 a novější, která závisí na Jacksonu 2.10. I když je kompatibilní se sadou Azure SDK pro Javu, vývojáři často zjistí, že se místo toho používá novější verze Jacksona, což vede k nekompatibilitě. Pokud chcete tento problém zmírnit, měli byste připnout konkrétní verzi Jacksona (která je kompatibilní se Sparkem). Další informace najdete v části Podpora více verzí Jackson v tomto článku.

Pokud používáte starší verze Sparku nebo pokud jiná knihovna, kterou používáte, vyžaduje ještě starší verzi Jacksona, kterou Sada Azure SDK pro Javu nepodporuje, pokračujte v tomto článku, kde najdete možné kroky pro zmírnění rizik.

Zjištění verze modulu runtime Jackson

V Azure Core 1.21.0 jsme přidali detekci modulu runtime a lepší diagnostiku verze modulu runtime Jackson.

Pokud se zobrazí LinkageError (nebo některá z jejích podtříd) souvisejících s rozhraním Jackson API, zkontrolujte zprávu výjimky s informacemi o verzi modulu runtime. Příklad: com.azure.core.implementation.jackson.JacksonVersionMismatchError: com/fasterxml/jackson/databind/cfg/MapperBuilder Package versions: jackson-annotations=2.9.0, jackson-core=2.9.0, jackson-databind=2.9.0, jackson-dataformat-xml=2.9.0, jackson-datatype-jsr310=2.9.0, azure-core=1.19.0-beta.2

Vyhledejte upozornění a protokoly chyb z JacksonVersion. Další informace najdete v tématu Konfigurace protokolování v sadě Azure SDK pro Javu. Příklad: [main] ERROR com.azure.core.implementation.jackson.JacksonVersion - Version '2.9.0' of package 'jackson-core' is not supported (too old), please upgrade.

Poznámka:

Zkontrolujte, že všechny balíčky Jackson mají stejnou verzi.

Seznam balíčků používaných sadou Azure SDK a podporovanými verzemi Jacksonu najdete v části Podpora více verzí Jacksonu.

Zmírnění problémů s neshodou verzí

Následující části popisují, jak zmírnit problémy s neshodou verzí.

Použití kusovníku sady Azure SDK

Použijte nejnovější stabilní KUSM sady Azure SDK a nezadávejte do souboru POM verze sady Azure SDK a závislostí. Pokud je to možné, použijte kusovník Azure Spring Boot.

Závislosti uvedené v kusovníku sady Azure SDK se testují pečlivě, aby nedocházelo ke konfliktům závislostí.

Vyhněte se zbytečným závislostem

Pokud je to možné, odeberte závislosti. Někdy má aplikace závislosti na více knihovnách, které poskytují v podstatě stejné funkce. Tyto zbytečné závislosti zpřístupňují aplikace ohrožením zabezpečení, konfliktům verzí a nákladům na podporu a údržbu.

Aktualizace verzí závislostí

Pokud přechod na nejnovější kusovníky sady Azure SDK nepomůže, identifikujte knihovny, které způsobují konflikty, a komponenty, které je používají. (Další informace najdete v tématu Zobrazení oddílu stromu závislostí dříve v tomto článku.) Zkuste aktualizovat na novější verzi, která chrání před ohroženími zabezpečení, a často přináší nové funkce, vylepšení výkonu a opravy chyb.

Vyhněte se downgradu verze sady Azure SDK, protože může vystavit vaši aplikaci známým ohrožením zabezpečení a problémům.

Stínovat knihovny

Někdy neexistuje žádná kombinace knihoven, které spolupracují, a stínování přichází jako poslední možnost.

Poznámka:

Stínování má významné nevýhody: zvyšuje velikost balíčku a počet tříd v cestě k třídám, ztěžuje navigaci v kódu a ladění, nepřemístí kód JNI, přeruší odraz a může mimo jiné narušit licence na kód. Mělo by se použít až po vyčerpání dalších možností.

Stínování umožňuje zahrnout závislosti v rámci souboru JAR v době sestavení a pak přejmenovat balíčky a aktualizovat kód aplikace tak, aby používal kód ve stínovaném umístění. Konflikt závislostí kosočtverce už není problém, protože existují dvě různé kopie závislosti. Můžete stínovat knihovnu, která má konfliktní tranzitivní závislost nebo přímou závislost aplikace, jak je popsáno v následujícím seznamu:

  • Konflikt přechodných závislostí: Například knihovna A třetích stran vyžaduje Jackson 2.9, které sady Azure SDK nepodporují a není možné je aktualizovat A. Vytvořte nový modul, který zahrnuje A a odstíny (přemístí) Jackson 2.9 a volitelně i další závislosti A.
  • Konflikt závislostí aplikace: Aplikace používá Jackson 2.9 přímo. Zatímco pracujete na aktualizaci kódu, můžete stínovat a přemístit Jacksona 2.9 do nového modulu s přemísťovanými jacksonovými třídami.

Poznámka:

Vytvoření fat JAR s přemísťovanými jacksonovými třídami nevyřeší konflikt verzí v těchto příkladech – vynutí pouze jednu stínovanou verzi Jacksona.

Vytvoření fat JAR

Prostředí, jako jsou Databricks nebo Apache Spark, mají vlastní správu závislostí a poskytují běžné knihovny, jako je Jackson. Abyste se vyhnuli konfliktu s poskytnutými knihovnami, můžete vytvořit fat JAR, který obsahuje všechny závislosti. Další informace najdete v modulu plug-in shade Apache Maven. V mnoha případech se přemístěním jacksonových tříd (com.fasterxml.jackson) problém zmírní. V některých případech tato prostředí také přinášejí vlastní verzi sad Azure SDK, takže můžete být nuceni přemístit com.azure obor názvů tak, aby fungoval v konfliktu verzí.

Vysvětlení kompatibilních verzí závislostí

Informace o azure-corekonkrétních závislostech a jejich verzích najdete v azure-core v centrálním úložišti Maven. Následující tabulka uvádí některé obecné aspekty:

Dependency Podporované verze
Jackson Verze 2.10.0 a novější podverze jsou kompatibilní. Další informace najdete v části Podpora více verzí Jacksonu.
SLF4J 1.7.*
netty-tcnative-boringssl-static 2.0.*
netty- common 4.1.*
jádro reaktoru 3.X.* – Čísla hlavních verzí a podverze musí přesně odpovídat těm, na kterých vaše azure-core verze závisí. Další informace najdete v zásadách projektu Reactor pro vyřazení.

Podpora více verzí Jacksonu

Sada Azure SDK pro Javu podporuje práci s řadou verzí Jackson. Nejnižší podporovaná verze je Jackson 2.10.0. Klientské knihovny Azure SDK pro Javu upravují konfiguraci a využití Jacksona v závislosti na verzi, která se detekuje za běhu. Tato úprava umožňuje větší kompatibilitu se staršími verzemi architektury Spring, Apache Sparku a dalšími běžnými prostředími. Aplikace můžou downgradovat verze Jacksonu (na verzi 2.10.0 nebo vyšší), aniž by porušily sadu Azure SDK pro klientské knihovny Java.

Poznámka:

Používání starých verzí Jacksonu může vystavit aplikace známým ohrožením zabezpečení a problémům. Další informace najdete v seznamu známých ohrožení zabezpečení pro knihovny Jackson.

Při připnutí konkrétní verze Jacksonu se ujistěte, že to uděláte pro všechny moduly používané sadou Azure SDK, které jsou uvedené v následujícím seznamu:

  • jackson-annotations
  • jackson-core
  • jackson-databind
  • jackson-dataformat-xml
  • jackson-datatype-jsr310

Další kroky

Teď, když už znáte konflikty verzí závislostí a způsob jejich řešení, najdete v tématu Správa závislostí pro Javu informace o nejlepším způsobu, jak jim zabránit.