Delen via


Problemen met afhankelijkheidsversies oplossen

In dit artikel worden afhankelijkheidsversieconflicten beschreven en hoe u deze problemen kunt oplossen.

Azure-clientbibliotheken voor Java zijn afhankelijk van populaire bibliotheken van derden, zoals de volgende:

Veel Java-toepassingen en -frameworks gebruiken deze bibliotheken rechtstreeks of transitief, wat leidt tot versieconflicten. Afhankelijkheden, zoals Maven en Gradle , worden alle afhankelijkheden omgezet, zodat er slechts één versie van elke afhankelijkheid van het klassepad is. Het is echter niet gegarandeerd dat de opgeloste afhankelijkheidsversie compatibel is met alle consumenten van die afhankelijkheid in uw toepassing. Zie Inleiding tot het mechanisme voor afhankelijkheden in de Maven-documentatie en Inzicht in afhankelijkheidsoplossing in de Gradle-documentatie voor meer informatie.

De API-incompatibiliteit van directe afhankelijkheden resulteert in compilatiefouten. Diamantafhankelijkheidsincompatibiliteit resulteert meestal in runtimefouten zoals NoClassDefFoundError, NoSuchMethodError of andere LinkageError. Niet alle bibliotheken volgen semantische versiebeheer en wijzigingen die fouten veroorzaken, vinden soms plaats in dezelfde primaire versie.

Problemen met niet-overeenkomende versies vaststellen

In de volgende secties worden methoden beschreven voor het vaststellen van problemen met niet-overeenkomende versies.

Het hulpprogramma Azure SDK voor Java-build gebruiken

Het hulpprogramma Azure SDK voor Java-build, geïntroduceerd in Aan de slag met Azure SDK en Apache Maven, helpt bij het identificeren van veelvoorkomende problemen. U wordt aangeraden dit buildhulpprogramma aan uw project toe te voegen en uit te voeren door het azure:run Maven-doel toe te voegen aan uw reguliere buildproces. Met de juiste configuratie kunt u afhankelijkheidsconflicten proactief identificeren en oplossen voordat ze tijdens runtime problemen worden.

Een afhankelijkheidsstructuur weergeven

Voer mvn dependency:tree de volledige afhankelijkheidsstructuur voor uw toepassing uit of gradle dependencies --scan geef deze weer met versienummers. mvn dependency:tree -Dverbose geeft meer informatie, maar kan misleidend zijn. Zie de Apache Maven-afhankelijkheidsstructuur in de Maven-documentatie voor meer informatie. Voor elke bibliotheek waarvan u vermoedt dat er een versieconflict is, noteert u het versienummer en bepaalt u welke onderdelen ervan afhankelijk zijn.

Afhankelijkheidsoplossing in ontwikkel- en productieomgevingen werkt mogelijk anders. Apache Spark-, Apache Flink-, Databricks- en IDE-invoegtoepassingen hebben extra configuratie nodig voor aangepaste afhankelijkheden. Ze kunnen ook hun eigen versies van Azure-clientbibliotheken of algemene onderdelen meenemen. Raadpleeg voor meer informatie de volgende artikelen:

Zie de sectie Een vet JAR maken verderop in dit artikel voor meer informatie over conflictoplossing in dergelijke omgevingen.

Azure Functions configureren

De interne afhankelijkheidsversie van Azure Functions (alleen met Java 8) heeft voorrang op een door de gebruiker opgegeven versie. Deze afhankelijkheid veroorzaakt versieconflicten, met name met Jackson, Netty en Reactor.

Als u dit probleem wilt oplossen, stelt u de FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS omgevingsvariabele in op true of 1. Zorg ervoor dat u de Azure Function Tools (v2 of v3) bijwerkt naar de nieuwste versie.

Notitie

Deze configuratie is alleen van toepassing op Azure Functions met Alleen Java 8, functies met Java 11 hebben geen speciale configuratie nodig.

Apache Spark configureren

De Azure SDK voor Java ondersteunt meerdere versies van Jackson, maar soms kunnen er problemen optreden, afhankelijk van uw buildhulpprogramma's en de volgorde van afhankelijkheidsoplossing. Een goed voorbeeld van dit probleem is met Apache Spark, versie 3.0.0 en hoger, wat afhankelijk is van Jackson 2.10. Hoewel het compatibel is met de Azure SDK voor Java, ontdekken ontwikkelaars vaak dat een recentere versie van Jackson wordt gebruikt, wat tot incompatibiliteit leidt. Als u dit probleem wilt verhelpen, moet u een specifieke versie van Jackson vastmaken (een versie die compatibel is met Spark). Zie de sectie Ondersteuning voor meerdere Jackson-versies in dit artikel voor meer informatie.

Als u eerdere versies van Spark gebruikt of als voor een andere bibliotheek die u gebruikt, een nog eerdere versie van Jackson is vereist die de Azure SDK voor Java niet ondersteunt, leest u dit artikel verder voor mogelijke risicobeperkingsstappen.

Runtimeversie van Jackson detecteren

In Azure Core 1.21.0 hebben we runtimedetectie en betere diagnoses van de Runtime-versie van Jackson toegevoegd.

Als u (of een van de subklassen) met betrekking tot de Jackson-API ziet LinkageError , controleert u het bericht van de uitzondering op runtimeversiegegevens. Bijvoorbeeld: 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

Zoek naar waarschuwings- en foutlogboeken van JacksonVersion. Zie Logboekregistratie configureren in de Azure SDK voor Java voor meer informatie. Bijvoorbeeld:[main] ERROR com.azure.core.implementation.jackson.JacksonVersion - Version '2.9.0' of package 'jackson-core' is not supported (too old), please upgrade.

Notitie

Controleer of alle Jackson-pakketten dezelfde versie hebben.

Zie de sectie Ondersteuning voor meerdere Jackson-versies voor de lijst met pakketten die worden gebruikt door Azure SDK en de ondersteunde Jackson-versies .

Problemen met niet-overeenkomende versies beperken

In de volgende secties wordt beschreven hoe u problemen met niet-overeenkomende versies kunt beperken.

Azure SDK-BOM gebruiken

Gebruik de nieuwste stabiele Azure SDK BOM en geef geen Versies van Azure SDK en afhankelijkheden op in uw POM-bestand. Gebruik, indien van toepassing, de Azure Spring Boot BOM.

De afhankelijkheden die worden vermeld in de Azure SDK BOM worden grondig getest om afhankelijkheidsconflicten te voorkomen.

Vermijd onnodige afhankelijkheden

Verwijder desgewenst afhankelijkheden. Soms heeft een toepassing afhankelijkheden van meerdere bibliotheken die in wezen dezelfde functionaliteit bieden. Dergelijke onnodige afhankelijkheden stellen toepassingen bloot aan beveiligingsproblemen, versieconflicten en ondersteunings- en onderhoudskosten.

Afhankelijkheidsversies bijwerken

Als het overschakelen naar de nieuwste Azure SDK-BOM niet helpt, identificeert u de bibliotheken die conflicten veroorzaken en de onderdelen die deze gebruiken. (Zie voor meer informatie de Bekijk een sectie van een afhankelijkheidsstructuur eerder in dit artikel.) Probeer bij te werken naar een nieuwere versie, die bescherming biedt tegen beveiligingsproblemen en vaak nieuwe functies, prestatieverbeteringen en oplossingen voor fouten bevat.

Vermijd het downgraden van de Azure SDK-versie omdat uw toepassing mogelijk wordt blootgesteld aan bekende beveiligingsproblemen en problemen.

Schaduwbibliotheken

Soms is er geen combinatie van bibliotheken die samenwerken, en arcering komt als laatste redmiddel.

Notitie

Arcering heeft aanzienlijke nadelen: het verhoogt de pakketgrootte en het aantal klassen op het klassepad, maakt codenavigatie en foutopsporing moeilijk, verplaatst JNI-code niet, breekt reflectie en kan onder andere codelicenties schenden. Deze moet alleen worden gebruikt nadat andere opties zijn uitgeput.

Met arcering kunt u afhankelijkheden opnemen in een JAR tijdens het bouwen, vervolgens de naam van pakketten wijzigen en toepassingscode bijwerken om de code op de gearceerde locatie te gebruiken. Een conflict tussen diamantafhankelijkheid is geen probleem meer omdat er twee verschillende kopieën van een afhankelijkheid zijn. U kunt een bibliotheek met een conflicterende transitieve afhankelijkheid of een directe toepassingsafhankelijkheid arceren, zoals wordt beschreven in de volgende lijst:

  • Conflict met transitieve afhankelijkheid: voor een bibliotheek A van derden is jackson 2.9 vereist, die azure-SDK's niet ondersteunen en het is niet mogelijk om bij te werken A. Maak een nieuwe module, die jackson 2.9 bevat A en tinten (verplaatst) en, optioneel, andere afhankelijkheden van A.
  • Conflict met toepassingsafhankelijkheid: uw toepassing maakt rechtstreeks gebruik van Jackson 2.9. Terwijl u aan het bijwerken van uw code werkt, kunt u Jackson 2.9 arceren en verplaatsen naar een nieuwe module met verplaatste Jackson-klassen.

Notitie

Het maken van vet-JAR met verplaatste Jackson-klassen lost geen versieconflict op in deze voorbeelden. Het dwingt slechts één gearceerde versie van Jackson af.

Een vet JAR-bestand maken

Omgevingen zoals Databricks of Apache Spark hebben aangepast afhankelijkheidsbeheer en bieden algemene bibliotheken zoals Jackson. Om conflicten met opgegeven bibliotheken te voorkomen, kunt u een vet JAR maken die alle afhankelijkheden bevat. Zie de Apache Maven Shade-invoegtoepassing voor meer informatie. In veel gevallen vermindert het verplaatsen van Jackson-klassen (com.fasterxml.jackson) het probleem. Soms brengen dergelijke omgevingen ook hun eigen versie van Azure SDK's mee, zodat u mogelijk wordt gedwongen om naamruimte te verplaatsen com.azure om versieconflicten te omzeilen.

Compatibele afhankelijkheidsversies begrijpen

Zie azure-core in de Centrale opslagplaats van Maven voor informatie over azure-core-specifieke afhankelijkheden en hun versies. In de volgende tabel ziet u enkele algemene overwegingen:

Dependency Ondersteunde versies
Jackson 2.10.0 en nieuwere secundaire versies zijn compatibel. Zie de sectie Ondersteuning voor meerdere Jackson-versies voor meer informatie.
SLF4J 1.7.*
netty-tcnative-boringssl-static 2.0.*
netty-common 4.1.*
reactorkern 3.X.* - Primaire en secundaire versienummers moeten exact overeenkomen met de nummers waarop uw azure-core versie afhankelijk is. Zie het project reactorbeleid voor afschaffingen voor meer informatie.

Ondersteuning voor meerdere Jackson-versies

De Azure SDK voor Java biedt ondersteuning voor het werken met een reeks Jackson-versies. De laagste ondersteunde versie is Jackson 2.10.0. De Azure SDK voor Java-clientbibliotheken passen hun configuratie en jacksongebruik aan, afhankelijk van de versie die tijdens runtime wordt gedetecteerd. Deze aanpassing maakt een grotere compatibiliteit mogelijk met oudere versies van het Spring-framework, Apache Spark en andere algemene omgevingen. Toepassingen kunnen Jackson-versies (naar 2.10.0 of hoger) downgraden zonder azure SDK voor Java-clientbibliotheken te breken.

Notitie

Het gebruik van oude versies van Jackson kan toepassingen blootstellen aan bekende beveiligingsproblemen en problemen. Zie de lijst met bekende beveiligingsproblemen voor Jackson-bibliotheken voor meer informatie.

Wanneer u een specifieke versie van Jackson vastmaken, moet u dit doen voor alle modules die door De Azure SDK worden gebruikt. Deze worden weergegeven in de volgende lijst:

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

Migratie van Jackson naar azure-json

Azure-clientbibliotheken voor Java zijn bezig met migratie naar azure-json, die niet afhankelijk is van onderdelen van derden en gedeelde primitieven, abstracties en helpers voor JSON biedt.

Omgevingen zoals Apache Spark, Apache Flink en Databricks kunnen oudere versies azure-core van die nog niet afhankelijk zijn azure-jsonvan. Als u nieuwere versies van Azure-bibliotheken in dergelijke omgevingen gebruikt, krijgt u mogelijk fouten die vergelijkbaar zijn met java.lang.NoClassDefFoundError: com/azure/json/JsonSerializable. U kunt deze fout beperken door een expliciete afhankelijkheid toe te voegen aan azure-json.

Volgende stappen

Nu u bekend bent met conflicten met afhankelijkheidsversies en hoe u problemen kunt oplossen, raadpleegt u Dependency Management voor Java voor informatie over de beste manier om deze te voorkomen.