Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här artikeln beskrivs konflikter i beroendeversioner och hur du felsöker dem.
Azure klientbibliotek för Java är beroende av populära bibliotek från tredje part, till exempel följande:
Många Java program och ramverk använder dessa bibliotek direkt eller transitivt, vilket leder till versionskonflikter. Beroendehanterare som Maven och Gradle löser alla beroenden så att det bara finns en enda version av varje beroende på klassökvägen. Det är dock inte garanterat att den lösta beroendeversionen är kompatibel med alla användare av det beroendet i ditt program. Mer information finns i Introduktion till beroendemekanismen i Maven-dokumentationen och Förstå beroendematchning i Gradle-dokumentationen.
API:ets inkompatibilitet för direkta beroenden resulterar i kompileringsfel. Inkompatibilitet med diamantberoenden resulterar vanligtvis i körningsfel som NoClassDefFoundError, NoSuchMethodError eller annat LinkageError. Alla bibliotek följer inte strikt semantisk versionshantering, och icke-bakåtkompatibla ändringar sker ibland i samma huvudversion.
Diagnostisera problem med versioners kompatibilitet
I följande avsnitt beskrivs metoder för hur du diagnostiserar problem med versionsmatchningsfel.
Använd Azure SDKs för Java build-verktyget
Verktyget Azure SDKs för Java, som introducerades i Get started with Azure SDKs and Apache Maven, hjälper till att identifiera vanliga problem. Lägg till det här byggverktyget i projektet och kör det genom att lägga till azure:run Maven-målet i din vanliga byggprocess. Med rätt konfiguration kan du identifiera och lösa beroendekonflikter mer proaktivt innan de blir problem vid körning.
Visa ett beroendeträd
Kör mvn dependency:tree eller gradle dependencies --scan för att visa det fullständiga beroendeträdet för ditt program med versionsnummer.
mvn dependency:tree -Dverbose ger mer information, men det kan vara missvisande. Mer information finns i Apache Maven Dependency Tree i Maven-dokumentationen. Anteckna versionsnumret för varje bibliotek som du misstänker har en versionskonflikt och ta reda på vilka komponenter som är beroende av det.
Beroenderesolution i utvecklings- och produktionsmiljöer kan fungera annorlunda. Apache Spark-, Apache Flink-, Databricks- och IDE-plugin-program behöver extra konfiguration för anpassade beroenden. De kan också ta med sina egna versioner av Azure klientbibliotek eller vanliga komponenter. Mer information finns i följande artiklar:
- Paketera programmets beroenden för Apache Spark
- Projektkonfiguration för Apache Flink
- Så här uppdaterar du ett Maven-bibliotek i Databricks för Databricks korrekt
Mer information om konfliktlösning i sådana miljöer finns i avsnittet Skapa en fet JAR senare i den här artikeln.
Konfigurera Azure Functions
Den interna beroendeversionen på Azure Functions (som endast kör Java 8) har företräde framför en användarversion. Det här beroendet orsakar versionskonflikter, särskilt med Jackson, Netty och Reactor.
Lös problemet genom att ange FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS miljövariabeln till true eller 1. Se till att uppdatera Azure Funktionsverktyg (v2 eller v3) till den senaste versionen.
Anmärkning
Den här konfigurationen gäller endast för Azure Functions som kör Java 8. Funktioner som kör Java 11 behöver inte någon särskild konfiguration.
Konfigurera Apache Spark
Azure SDKs för Java stöder flera versioner av Jackson, men ibland kan problem uppstå beroende på din byggverktyg och dess beroendematchningsordning. Ett bra exempel på det här problemet är med Apache Spark, version 3.0.0 och senare, som är beroende av Jackson 2.10. Även om det är kompatibelt med Azure SDKs för Java upptäcker utvecklare ofta att en nyare version av Jackson används i stället, vilket resulterar i inkompatibiliteter. Du kan åtgärda det här problemet genom att fästa en specifik version av Jackson (en som är kompatibel med Spark). Mer information finns i avsnittet Support för flera Jackson-versioner i den här artikeln.
Om du använder tidigare versioner av Spark, eller om ett annat bibliotek som du använder kräver en ännu tidigare version av Jackson som Azure SDKs för Java inte stöder, fortsätter du att läsa den här artikeln för möjliga åtgärdssteg.
Identifiera Jackson-körningsversion
I Azure Core 1.21.0 lägger biblioteket till identifiering av körningsmiljön och bättre diagnostik för Jacksons runtimeversion.
Om du ser LinkageError (eller någon av dess underklasser) som är relaterade till Jackson-API:et, kontrollerar du meddelandet om undantaget för att få information om körningsversionen. Till exempel: 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
Leta efter varnings- och felloggar från JacksonVersion. Mer information finns i Konfigurera loggning i Azure SDKs för Java. Till exempel: [main] ERROR com.azure.core.implementation.jackson.JacksonVersion - Version '2.9.0' of package 'jackson-core' is not supported (too old), please upgrade.
Anmärkning
Kontrollera att alla Jackson-paket har samma version.
Listan över paket som används av Azure SDKs och de Jackson-versioner som stöds finns i avsnittet Support för flera Jackson-versioner.
Åtgärda problem med versionsmatchning
I följande avsnitt beskrivs hur du åtgärdar problem med versionsmatchningsfel.
Använda Azure SDKs BOM
Använd den senaste stabila Azure SDKs BOM och ange inte Azure SDKs och beroendeversioner i POM-filen. När det är tillämpligt använder du Azure Spring Boot BOM.
Beroenden som anges i Azure SDKs BOM testas noggrant för att undvika beroendekonflikter.
Undvik onödiga beroenden
Ta bort beroenden om du kan. Ibland har ett program beroenden på flera bibliotek som ger i stort sett samma funktioner. Sådana onödiga beroenden utsätter program för säkerhetsrisker, versionskonflikter och support- och underhållskostnader.
Uppdatera beroendeversioner
Om det inte hjälper att växla till den senaste Azure SDKs strukturlistan kan du identifiera de bibliotek som orsakar konflikter och de komponenter som använder dem. (Mer information finns i avsnittet Visa ett beroendeträd tidigare i den här artikeln.) Prova att uppdatera till en nyare version som skyddar mot säkerhetsrisker och ofta innehåller nya funktioner, prestandaförbättringar och felkorrigeringar.
Undvik att nedgradera den Azure SDKs versionen eftersom den kan utsätta ditt program för kända sårbarheter och problem.
Skuggbibliotek
Ibland finns det ingen kombination av bibliotek som fungerar tillsammans, och skuggning kommer som den sista utvägen.
Anmärkning
Skuggning har betydande nackdelar: det ökar paketstorleken och antalet klasser på klassökvägen, det gör kodnavigering och felsökning svårt, den flyttar inte JNI-kod, bryter reflektionen och det kan bryta mot kodlicenser bland annat. Använd den först när andra alternativ är uttömda.
Med skuggning kan du inkludera beroenden i en JAR vid byggtiden, byta namn på paket och uppdatera programkoden så att koden används på den skuggade platsen. Diamantberoendekonflikter är inte längre ett problem eftersom det finns två olika kopior av ett beroende. Du kan skugga ett bibliotek som har ett transitivt beroende i konflikt eller ett direkt programberoende enligt beskrivningen i följande lista:
-
Översatt beroendekonflikt: Till exempel kräver bibliotek från tredje part
AJackson 2.9, vilket Azure-SDK:er inte stöder, och det går inte att uppdateraA. Skapa en ny modul, som innehållerAoch nyanser (flyttar) Jackson 2.9 och, om du vill, andra beroenden avA. - Programberoendekonflikt: Programmet använder Jackson 2.9 direkt. Medan du arbetar med att uppdatera koden kan du skugga och flytta Jackson 2.9 till en ny modul med flyttade Jackson-klasser i stället.
Anmärkning
Att skapa fet JAR med flyttade Jackson-klasser löser inte en versionskonflikt i dessa exempel – det tvingar bara fram en enda skuggad version av Jackson.
Skapa en fet JAR
Miljöer som Databricks eller Apache Spark har anpassad beroendehantering och tillhandahåller vanliga bibliotek som Jackson. För att undvika konflikter med de bibliotek som tillhandahålls kanske du vill skapa en fet JAR som innehåller alla beroenden. Mer information finns i Apache Maven Shade Plugin. I många fall mildrar problemet genom att omlokalisera Jackson-klasserna (com.fasterxml.jackson). Ibland tar sådana miljöer också med sig en egen version av Azure-SDK:er, så du kan behöva flytta com.azure namnområdet för att kringgå versionskonflikter.
Förstå kompatibla beroendeversioner
Information om azure-core-specifika beroenden och deras versioner finns i azure-core på Den centrala Maven-lagringsplatsen. Följande tabell visar några allmänna överväganden:
| Beroende | Versioner som stöds |
|---|---|
| Jackson | 2.10.0 och senare delversioner är kompatibla. Mer information finns i avsnittet Support för flera Jackson-versioner . |
| SLF4J | 1.7.* |
| netty-tcnative-boringssl-static | 2.0.* |
| netty-common (only if it is a product name or technical term without a Swedish equivalent) | 4.1.* |
| reaktorkärna | 3.X.* – Huvud- och delversionsnummer måste exakt matcha de som din azure-core version är beroende av. Mer information finns i Project Reactor-principen om utfasningar. |
Stöd för flera Jackson-versioner
Azure SDKs för Java stöder arbete med en rad olika Jackson-versioner. Den version som stöds lägst är Jackson 2.10.0. Azure SDKs för Java klientbibliotek justerar konfigurationen och Jackson-användningen beroende på vilken version som identifieras vid körning. Den här justeringen möjliggör större kompatibilitet med äldre versioner av Spring-ramverket, Apache Spark och andra vanliga miljöer. Program kan nedgradera Jackson-versioner (till 2.10.0 eller senare) utan att bryta Azure SDKs för Java klientbibliotek.
Anmärkning
Om du använder gamla versioner av Jackson kan program utsättas för kända sårbarheter och problem. Mer information finns i listan över kända sårbarheter för Jackson-bibliotek.
När du fäster en specifik version av Jackson måste du göra det för alla moduler som används av Azure SDKs, som visas i följande lista:
jackson-annotationsjackson-corejackson-databindjackson-dataformat-xmljackson-datatype-jsr310
Migrering från Jackson till azure-json
Azure klientbibliotek för Java migreras till azure-json, som inte är beroende av komponenter från tredje part. Den erbjuder delade primitiver, abstraktioner och hjälpverktyg för JSON.
Miljöer som Apache Spark, Apache Flink och Databricks kan medföra äldre versioner av azure-core som ännu inte är beroende av azure-json. När du använder nyare versioner av Azure bibliotek i sådana miljöer kan du därför få fel som liknar java.lang.NoClassDefFoundError: com/azure/json/JsonSerializable. Lägg till ett uttryckligt beroende av azure-json för att åtgärda det här felet.
Nästa steg
Nu när du är bekant med beroendeversionskonflikter och hur du felsöker dem kan du läsa Beroendehantering för Java för information om det bästa sättet att förhindra dem.