Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cet article décrit les conflits de version des dépendances et explique comment les résoudre.
Azure bibliothèques clientes pour Java dépendent de bibliothèques tierces populaires telles que les bibliothèques suivantes :
De nombreuses applications et infrastructures Java utilisent ces bibliothèques directement ou transitivement, ce qui entraîne des conflits version. Les gestionnaires de dépendances tels que Maven et Gradle résolvent toutes les dépendances afin qu’il n’existe qu’une seule version de chaque dépendance sur le classpath. Toutefois, il n’est pas garanti que la version de dépendance résolue soit compatible avec tous les consommateurs de cette dépendance dans votre application. Pour plus d’informations, consultez Présentation du mécanisme de dépendance dans la documentation Maven et Présentation de la résolution des dépendances dans la documentation Gradle.
L’incompatibilité de l’API des dépendances directes entraîne des erreurs de compilation. L’incompatibilité des dépendances Diamond aboutit généralement à des échecs d’exécution comme NoClassDefFoundError, NoSuchMethodError ou encore LinkageError. Les bibliothèques ne suivent pas toutes de façon stricte la gestion sémantique des versions, et des changements cassants se produisent parfois dans la même version principale.
Diagnostiquer les problèmes d’incompatibilité de version
Les sections suivantes décrivent les méthodes permettant de diagnostiquer les problèmes d’incompatibilité de version.
Utiliser le SDK Azure pour Java avec l'outil de compilation
L'outil de génération Java du SDK Azure, introduit dans Démarrer avec Azure SDK et Apache Maven, permet d’identifier les problèmes couramment rencontrés. Nous vous recommandons d’ajouter cet outil de génération à votre projet et de l’exécuter en ajoutant la azure:run cible Maven à votre processus de génération standard. Avec la configuration appropriée, vous pouvez identifier et résoudre les conflits de dépendance de manière plus proactive avant qu’ils ne deviennent des problèmes au moment de l’exécution.
Afficher une arborescence de dépendances
Exécutez mvn dependency:tree ou gradle dependencies --scan pour afficher l’arborescence de dépendances complète de votre application, avec des numéros de version.
mvn dependency:tree -Dverbose donne plus d’informations, mais peut être trompeuse. Pour plus d’informations, consultez l’arborescence des dépendances Apache Maven dans la documentation Maven. Pour chaque bibliothèque que vous pensez avoir un conflit de version, notez son numéro de version et déterminez les composants qui en dépendent.
La résolution des dépendances dans les environnements de développement et de production peut fonctionner différemment. Les plug-ins Apache Spark, Apache Flink, Databricks et IDE nécessitent une configuration supplémentaire pour les dépendances personnalisées. Ils peuvent également apporter leurs propres versions de Azure bibliothèques clientes ou composants communs. Pour plus d’informations, consultez les articles suivants :
- Regroupement des dépendances de votre application pour Apache Spark
- Configuration du projet pour Apache Flink
- Comment mettre à jour correctement une bibliothèque Maven dans Databricks pour Databricks
Pour plus d’informations sur la résolution des conflits dans ces environnements, consultez la section Créer un fichier JAR gras plus loin dans cet article.
Configurer Azure Functions
La version de dépendance interne sur Azure Functions (en cours d’exécution Java 8 uniquement) est prioritaire sur une version fournie par l’utilisateur. Cette dépendance provoque des conflits de version, en particulier avec Jackson, Netty et Reactor.
Pour résoudre ce problème, définissez la variable d’environnement FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS sur true ou 1. Veillez à mettre à jour les outils de fonction Azure (v2 ou v3) vers la dernière version.
Remarque
Cette configuration s'applique à Azure Functions en cours d'exécution Java 8 uniquement, les fonctions exécutant Java 11 n'ont pas besoin d'une configuration spéciale.
Configurer Apache Spark
Le Azure SDK pour Java prend en charge plusieurs versions de Jackson, mais les problèmes peuvent parfois survenir en fonction de vos outils de génération et de son ordre de résolution des dépendances. Un bon exemple de ce problème est lié à Apache Spark, version 3.0.0 et ultérieure, qui dépend de Jackson 2.10. Bien qu'il soit compatible avec le Azure SDK pour Java, les développeurs découvrent souvent qu'une version plus récente de Jackson est utilisée à la place, ce qui entraîne des incompatibilités. Pour atténuer ce problème, vous devez épingler une version spécifique de Jackson (compatible avec Spark). Pour plus d'informations, consultez la section Soutien pour plusieurs versions de Jackson dans cet article.
Si vous utilisez des versions antérieures de Spark ou si une autre bibliothèque que vous utilisez nécessite une version même antérieure de Jackson que la Azure SDK pour Java ne prend pas en charge, poursuivez la lecture de cet article pour connaître les étapes d'atténuation possibles.
Détecter la version d’exécution de Jackson
Dans Azure Core 1.21.0, nous avons ajouté la détection du runtime et de meilleurs diagnostics de la version du runtime Jackson.
Si vous voyez LinkageError (ou l’une de ses sous-classes) liées à l’API Jackson, vérifiez le message de l’exception pour obtenir des informations sur la version du runtime. Par exemple : 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
Rechercher les journaux d’avertissement et d'erreur dans JacksonVersion. Pour plus d’informations, consultez Configurer la journalisation dans le SDK Azure pour Java. Par exemple : [main] ERROR com.azure.core.implementation.jackson.JacksonVersion - Version '2.9.0' of package 'jackson-core' is not supported (too old), please upgrade.
Remarque
Vérifiez que tous les packages Jackson ont la même version.
Pour obtenir la liste des packages utilisés par Azure SDK et les versions de Jackson prises en charge, consultez la section Support pour plusieurs versions de Jackson.
Atténuer les problèmes d’incompatibilité de version
Les sections suivantes décrivent comment atténuer les problèmes d’incompatibilité de version.
Utiliser Azure SDK BOM
Utilisez la dernière version stable Azure SDK BOM et ne spécifiez pas les versions Azure SDK et de dépendances dans votre fichier POM. Le cas échéant, utilisez le Azure BoM Spring Boot.
Les dépendances répertoriées dans le Azure SDK BOM sont testées rigoureusement pour éviter les conflits de dépendances.
Éviter les dépendances inutiles
Supprimez les dépendances si vous le pouvez. Parfois, une application a des dépendances sur plusieurs bibliothèques qui fournissent essentiellement la même fonctionnalité. Ces dépendances inutiles exposent les applications aux vulnérabilités de sécurité, aux conflits de version et aux coûts de prise en charge et de maintenance.
Mettre à jour les versions des dépendances
Si le passage à la dernière Azure SDK BOM n'aide pas, identifiez les bibliothèques qui causent des conflits, ainsi que les composants qui les utilisent. (Pour plus d’informations, consultez la section Afficher une arborescence de dépendances plus haut dans cet article.) Essayez de mettre à jour vers une version plus récente, qui protège contre les vulnérabilités de sécurité et apporte souvent de nouvelles fonctionnalités, améliorations des performances et correctifs de bogues.
Évitez de rétrograder la version Azure SDK, car elle peut exposer votre application aux vulnérabilités et problèmes connus.
Bibliothèques de nuances
Parfois, il n’y a pas de combinaison de bibliothèques qui fonctionnent ensemble, et l’ombrage vient comme le dernier recours.
Remarque
L’ombrage présente des inconvénients significatifs : il augmente la taille du package et le nombre de classes sur le classpath, il rend la navigation et le débogage du code dur, ne déplace pas le code JNI, interrompt la réflexion et peut violer les licences de code entre autres. Elle ne doit être utilisée qu’une fois que d’autres options sont épuisées.
L’ombrage vous permet d’inclure des dépendances au sein d’un fichier JAR au moment de la génération, puis de renommer des packages et de mettre à jour le code d’application pour utiliser le code à l’emplacement ombré. Le conflit de dépendances de diamant n’est plus un problème, car il existe deux copies différentes d’une dépendance. Vous pouvez nuancer une bibliothèque qui a une dépendance transitive conflictuelle ou une dépendance d’application directe, comme décrit dans la liste suivante :
-
Conflit de dépendances transitive : par exemple, la bibliothèque tierce
Anécessite Jackson 2.9, que les SDKs Azure ne prennent pas en charge, et il n'est pas possible de mettre à jourA. Créez un nouveau module, qui comprendAet ombre (déplace) Jackson 2.9 et éventuellement d’autres dépendances deA. - Conflit de dépendance d’application : votre application utilise Jackson 2.9 directement. Pendant que vous travaillez sur la mise à jour de votre code, vous pouvez utiliser le shading pour déplacer Jackson 2.9 dans un nouveau module avec des classes Jackson relocalisées.
Remarque
La création d'un JAR complet avec des classes Jackson relocalisées ne résout pas un conflit de version dans ces exemples : elle impose simplement une version unique et ombrée de Jackson.
Créer un gros fichier JAR
Les environnements tels que Databricks ou Apache Spark ont une gestion des dépendances personnalisée et fournissent des bibliothèques courantes comme Jackson. Pour éviter les conflits avec les bibliothèques fournies, vous pouvez créer un fichier JAR gras qui contient toutes les dépendances. Pour plus d’informations, consultez le plug-in Apache Maven Shade. Dans de nombreux cas, le déplacement des classes Jackson (com.fasterxml.jackson) atténue le problème. Parfois, ces environnements apportent également leur propre version de Azure SDKs. Vous pouvez donc être obligé de déplacer com.azure espace de noms pour contourner les conflits de version.
Comprendre les versions de dépendance compatibles
Pour en savoir plus sur les dépendances spécifiques à azure-core et leurs versions, consultez azure-core dans le dépôt Maven Central. Le tableau suivant présente quelques considérations générales :
| Dépendance | Versions prises en charge |
|---|---|
| Jackson | 2.10.0 et versions mineures plus récentes sont compatibles. Pour plus d’informations, consultez la section Prise en charge de plusieurs versions de Jackson. |
| SLF4J | 1.7.* |
| netty-tcnative-boringssl-static | 2.0.* |
| netty-common | 4.1.* |
| cœur du réacteur | 3.X.* : les numéros de version principale et mineure doivent correspondre exactement à ceux dont dépend votre azure-core version. Pour plus d’informations, consultez la politique Project Reactor sur les dépréciations. |
Prise en charge de plusieurs versions de Jackson
Le SDK Azure pour Java prend en charge l’utilisation d'une gamme de versions Jackson. La version la plus faible prise en charge est Jackson 2.10.0. Les Azure SDK pour les bibliothèques clientes Java ajustent leur configuration et l’utilisation de Jackson en fonction de la version détectée lors de l’exécution. Cet ajustement permet une plus grande compatibilité avec les versions antérieures de l’infrastructure Spring, Apache Spark et d’autres environnements courants. Les applications peuvent rétrograder les versions de Jackson (vers la version 2.10.0 ou ultérieure) sans rompre Azure SDK pour les bibliothèques clientes Java.
Remarque
L’utilisation d’anciennes versions de Jackson peut exposer des applications à des vulnérabilités et problèmes connus. Pour plus d’informations, consultez la liste des vulnérabilités connues pour les bibliothèques Jackson.
Lors de l’épinglage d’une version spécifique de Jackson, veillez à le faire pour tous les modules utilisés par Azure SDK, qui sont affichés dans la liste suivante :
jackson-annotationsjackson-corejackson-databindjackson-dataformat-xmljackson-datatype-jsr310
Migration de Jackson vers azure-json
Azure bibliothèques clientes pour Java sont en cours de migration vers azure-json, qui ne dépend pas des composants tiers et propose des primitives, des abstractions et des helpers partagés pour JSON.
Les environnements comme Apache Spark, Apache Flink et Databricks peuvent apporter des versions plus anciennes de azure-core qui ne dépendent pas encore de azure-json. Par conséquent, lorsque vous utilisez des versions plus récentes de bibliothèques de Azure dans de tels environnements, vous pouvez obtenir des erreurs similaires à java.lang.NoClassDefFoundError: com/azure/json/JsonSerializable. Vous pouvez atténuer cette erreur en ajoutant une dépendance explicite sur azure-json.
Étapes suivantes
Maintenant que vous connaissez les conflits de version des dépendances et comment les résoudre, consultez Dependency Management for Java pour plus d'informations sur la meilleure façon de les empêcher.