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:
- De afhankelijkheden van uw toepassing bundelen voor Apache Spark
- Projectconfiguratie voor Apache Flink
- Een Maven-bibliotheek correct bijwerken in Databricks voor Databricks
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.
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 werkenA
. Maak een nieuwe module, die jackson 2.9 bevatA
en tinten (verplaatst) en, optioneel, andere afhankelijkheden vanA
. - 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-json
van. 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.