Függőségi verzióütközések elhárítása

Ez a cikk a függőségek verzióütközéseit és azok hibaelhárítását ismerteti.

Azure Java ügyfélkódtárai a népszerű külső kódtáraktól függenek, például az alábbiaktól:

Számos Java alkalmazás és keretrendszer közvetlenül vagy tranzitív módon használja ezeket a kódtárakat, ami verziós ütközésekhez vezet. A függőségkezelők, például a Maven és a Gradle minden függőséget feloldanak, hogy az osztályúton csak az egyes függőségek egyetlen verziója legyen. Azonban nem garantált, hogy a feloldott függőségi verzió kompatibilis az alkalmazás ezen függőségének összes fogyasztójával. További információ : Bevezetés a függőségi mechanizmusba a Maven dokumentációjában és a függőségfeloldás ismertetése a Gradle dokumentációjában.

A közvetlen függőségek API-inkompatibilitása fordítási hibákat eredményez. A gyémántfüggőség inkompatibilitása általában olyan futtatókörnyezeti hibákat eredményez, mint a NoClassDefFoundError, a NoSuchMethodError vagy más LinkageError. Nem minden kódtár szigorúan követi a szemantikai verziókövetést, és a kompatibilitástörő változások néha ugyanazon a főverzión belül történnek.

Verzióeltérési problémák diagnosztizálása

A következő szakaszok a verzióeltérési problémák diagnosztizálására vonatkozó módszereket ismertetik.

A Azure SDK használata Java buildelési eszközhöz

Az Azure SDK és az Apache Maven használatával megismerkedhet az Azure SDK for Java build eszközzel, amely segít azonosítani a gyakran előforduló problémákat. Adja hozzá ezt a buildelési eszközt a projekthez, és futtassa úgy, hogy hozzáadja a azure:run Maven-célt a szokásos buildelési folyamathoz. A megfelelő konfigurációval proaktívabban azonosíthatja és megoldhatja a függőségi ütközéseket, mielőtt futásidőben problémákba ütköznének.

Függőségi fa megtekintése

Futtassa mvn dependency:tree vagy gradle dependencies --scan jelenítse meg az alkalmazás teljes függőségi fáját verziószámokkal. mvn dependency:tree -Dverbose több információt ad, de félrevezető lehet. További információ: Apache Maven Dependency Tree a Maven dokumentációjában. Minden olyan kódtár esetében, amelyről gyanítható, hogy verzióütközés van, jegyezze fel annak verziószámát, és állapítsa meg, hogy mely összetevők függnek attól.

A fejlesztési és éles környezetekben a függőségfeloldás eltérően működhet. Az Apache Spark, az Apache Flink, a Databricks és az IDE beépülő moduloknak további konfigurációra van szükségük az egyéni függőségekhez. Emellett saját verziójú Azure ügyfélkódtárakat vagy közös összetevőket is használhatnak. További információkért lásd a következő cikkeket:

Az ilyen környezetekben előforduló ütközésfeloldásról a cikk későbbi, fat JAR létrehozása című szakaszában olvashat bővebben.

Azure Functions konfigurálása

A Azure Functions belső függőségi verziója (csak Java 8-at futtat) elsőbbséget élvez a felhasználó által biztosított verzióval szemben. Ez a függőség verzióütközéseket okoz, különösen a Jackson, a Netty és a Reactor esetén.

A probléma megoldásához állítsa a FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS környezeti változót true vagy 1 értékre. Mindenképpen frissítse a Azure függvényeszközöket (v2 vagy v3) a legújabb verzióra.

Megjegyzés:

Ez a konfiguráció csak a Java 8-on futó Azure Functionsre vonatkozik. A Java 11-et futtató függvények nem igényelnek speciális konfigurációt.

Az Apache Spark konfigurálása

A Java Azure SDK a Jackson több verzióját is támogatja, de a buildelési eszköztől és a függőségek megoldásának sorrendjétől függően néha problémák merülhetnek fel. Erre jó példa az Apache Spark 3.0.0-s és újabb verziója, amely a Jackson 2.10-es verziójától függ. Bár kompatibilis a Java Azure SDK, a fejlesztők gyakran tapasztalják, hogy a Jackson egy újabb verzióját használják, ami inkompatibilitást eredményez. A probléma megoldásához rögzítse a Jackson egy adott verzióját (amely kompatibilis a Sparkkal). További információt a jelen cikk Több Jackson-verzió támogatása című szakaszában talál.

Ha a Spark korábbi verzióit használja, vagy ha egy másik használt kódtárhoz a Jackson egy korábbi verziója szükséges, amelyet a Java Azure SDK nem támogat, olvassa el ezt a cikket a lehetséges megoldási lépésekért.

A Jackson-futtatókörnyezet verziójának észlelése

A Azure Core 1.21.0-s verziójában a kódtár futásidejű észlelést és jobb diagnosztikát biztosít a Jackson-futtatókörnyezet verziójához.

Ha a LinkageError-t (vagy bármelyik alosztályát) látja a Jackson API-val kapcsolatban, ellenőrizze a kivétel üzenetét a futtatókörnyezet verzióadatainak megismeréséhez. Például: 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

Keresse meg a figyelmeztetési és hibanaplókat a következőből JacksonVersion: . További információért lásd: Naplózás konfigurálása az Azure SDK for Java-ban. Például: [main] ERROR com.azure.core.implementation.jackson.JacksonVersion - Version '2.9.0' of package 'jackson-core' is not supported (too old), please upgrade.

Megjegyzés:

Ellenőrizze, hogy az összes Jackson-csomag ugyanazzal a verzióval rendelkezik-e.

A Azure SDK és a támogatott Jackson-verziók által használt csomagok listájáért tekintse meg a Támogatás több Jackson-verzióhoz szakaszt.

Verzióeltérési problémák elhárítása

A következő szakaszok ismertetik, hogyan hárítható el a verzióeltérésekkel kapcsolatos problémák.

Az Azure SDK BOM használata

Használja a legújabb stabil Azure SDK BOM, és ne adjon meg Azure SDK és függőségi verziókat a POM-fájlban. Szükség esetén használja a Azure Spring Boot BOM.

A Azure SDK anyagjegyzékben felsorolt függőségeket szigorúan teszteljük a függőségi ütközések elkerülése érdekében.

A szükségtelen függőségek elkerülése

Ha lehet, távolítsa el a függőségeket. Előfordulhat, hogy egy alkalmazás több kódtártól is függ, amelyek lényegében ugyanazt a funkciót biztosítják. Az ilyen szükségtelen függőségek biztonsági réseknek, verzióütközéseknek, valamint támogatási és karbantartási költségeknek teszik ki az alkalmazásokat.

Függőségi verziók frissítése

Ha a legújabb Azure SDK anyagjegyzékre való váltás nem segít, azonosítsa az ütközéseket okozó kódtárakat és az azokat használó összetevőket. (További információ: Függőségfa megtekintése szakasz a cikk korábbi részében.) Próbáljon meg újabb verzióra frissíteni, amely védelmet nyújt a biztonsági rések ellen, és gyakran új funkciókat, teljesítménybeli fejlesztéseket és hibajavításokat hoz létre.

Kerülje az Azure SDK-verzió visszaminősítését, mert az alkalmazását ismert sérülékenységeknek és problémáknak teheti ki.

Tárak árnyékolása

Néha a kódtárak nem működnek együtt, és az árnyékolás az utolsó megoldás.

Megjegyzés:

Az árnyékolásnak jelentős hátrányai vannak: növeli a csomag méretét és az osztályok számát az osztályúton, megnehezíti a kódnavigációt és a hibakeresést, nem helyezi át a JNI-kódot, megszakítja a tükröződést, és többek között megsértheti a kódlicenceket. Csak akkor használja, ha más lehetőségek kimerültek.

Az árnyékolás lehetővé teszi, hogy a buildeléskor függőségeket tartalmazzon a JAR-ban, majd átnevezze a csomagokat, és frissítse az alkalmazás kódját, hogy az árnyékolt helyen használja a kódot. A gyémántfüggőség ütközése már nem jelent problémát, mert egy függőség két különböző példánya létezik. Az ütköző tranzitív függőséget vagy közvetlen alkalmazásfüggőséget tartalmazó kódtárak árnyékolását az alábbi listában leírtak szerint végezheti el:

  • Transitive függőségi ütközés: Például a külső forráskódtár A igényli a Jackson 2.9-es verzióját, amelyet az Azure SDK nem támogat, és ez nem frissíthető A. Hozzon létre egy új modult, amely tartalmazza A és árnyékolja (áthelyezi) a Jackson 2.9-et, és opcionálisan a többi függőséget Ais.
  • Alkalmazásfüggőség-ütközés: Az alkalmazás közvetlenül a Jackson 2.9-et használja. Miközben a kód frissítésén dolgozik, árnyékolhatja és áthelyezheti a Jackson 2.9-et egy új modulba, helyette áthelyezett Jackson-osztályokkal.

Megjegyzés:

A kövér JAR létrehozása az áthelyezett Jackson-osztályokkal nem oldja meg a verzióütközést ezekben a példákban – csak a Jackson egyetlen árnyékolt verzióját kényszeríti ki.

Zsíros JAR létrehozása

Az olyan környezetek, mint a Databricks vagy az Apache Spark egyéni függőségkezeléssel rendelkeznek, és olyan gyakori kódtárakat biztosítanak, mint a Jackson. A megadott kódtárakkal való ütközés elkerülése érdekében érdemes lehet létrehozni egy kövér JAR-t, amely tartalmazza az összes függőséget. További információt az Apache Maven Shade beépülő modulban talál. A Jackson-osztályok (com.fasterxml.jackson) áthelyezése sok esetben enyhíti a problémát. Előfordulhat, hogy az ilyen környezetek saját Azure SDK-k-verziót is használnak, ezért előfordulhat, hogy át kell helyeznie com.azure a névteret a verzióütközések megkerüléséhez.

A kompatibilis függőségi verziók ismertetése

Az adott függőségekről és azok verzióiról azure-corea Maven Central-adattár azure-core című témakörében olvashat bővebben. Az alábbi táblázat néhány általános szempontot mutat be:

Függőség Támogatott verziók
Jackson A 2.10.0 és az újabb alverziók kompatibilisek. További információt a Több Jackson-verzió támogatása című szakaszban talál.
SLF4J 1.7.*
netty-tcnative-boringssl-static 2.0.*
netty-közös 4.1.*
reaktormag 3.X.* – A fő- és alverziószámoknak pontosan meg kell egyezniük azokkal, amelyektől a azure-core verzió függ. További információ: Project Reactor-szabályzat az elavulásokról.

Több Jackson-verzió támogatása

A Java Azure SDK számos Jackson-verzió használatát támogatja. A legalacsonyabb támogatott verzió a Jackson 2.10.0. Az Azure SDK Java ügyfélkönyvtárai a futási időben észlelt verziótól függően állítják be konfigurációjukat és módosítják a Jackson használatát. Ez a beállítás nagyobb kompatibilitást tesz lehetővé a Spring-keretrendszer, az Apache Spark és más gyakori környezetek régebbi verzióival. Az alkalmazások a Jackson-verziókat (2.10.0-s vagy újabb verzióra) visszaminősíthetik anélkül, hogy megsértenék az Azure SDK Java ügyfélkönyvtárakat.

Megjegyzés:

A Jackson régi verzióinak használata ismert biztonsági rések és problémák elé tárhatja az alkalmazásokat. További információkért tekintse meg a Jackson-kódtárak ismert biztonsági réseinek listáját.

A Jackson egy adott verziójának rögzítésekor győződjön meg arról, hogy az Azure SDK által használt összes modul esetében megteszi, amely az alábbi listában látható:

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

Migrálás Jacksonból az azure-jsonba

Azure Java ügyfélkódtárai azure-jsonra migrálnak, ami nem függ semmilyen külső összetevőtől. Megosztott primitíveket, absztrakciókat és segítőket kínál a JSON-hoz.

Az olyan környezetek, mint az Apache Spark, az Apache Flink és a Databricks, olyan régebbi verziókat azure-core is tartalmazhatnak, amelyek még nem függenek egymástól azure-json. Ennek eredményeképpen, ha ilyen környezetekben Azure kódtárak újabb verzióit használja, a következőhöz java.lang.NoClassDefFoundError: com/azure/json/JsonSerializablehasonló hibaüzenetek jelenhetnek meg. Adjon hozzá explicit függőséget a(z) azure-json elemhez a hiba kiküszöböléséhez.

Következő lépések

Most, hogy már ismeri a függőségi verzió ütközéseit és hibaelhárításukat, tekintse meg a Dependency Management for Java című témakört a megelőzés legjobb módjáról.