Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se describen los conflictos de versiones de dependencia y cómo solucionarlos.
Azure bibliotecas cliente para Java dependen de bibliotecas populares de terceros, como las siguientes:
- Jackson
- Netty
- Reactor
- SLF4J
Muchas aplicaciones y marcos de Java usan estas bibliotecas directamente o transitivamente, lo que conduce a conflictos de version. Los administradores de dependencias, como Maven y Gradle , resuelven todas las dependencias para que solo haya una sola versión de cada dependencia en la ruta de clase. Sin embargo, no se garantiza que la versión de dependencia resuelta sea compatible con todos los consumidores de esa dependencia en la aplicación. Para obtener más información, consulte Introducción al mecanismo de dependencia en la documentación de Maven y Descripción de la resolución de dependencias en la documentación de Gradle.
La incompatibilidad de las API de las dependencias directas resulta en errores de compilación. La incompatibilidad de dependencias en rombo suele dar lugar a errores en tiempo de ejecución como NoClassDefFoundError, NoSuchMethodError u otros de tipo LinkageError. No todas las bibliotecas siguen estrictamente la versión semántica, y a veces ocurren cambios importantes dentro de la misma versión principal.
Diagnóstico de problemas de coincidencia de versiones
En las secciones siguientes se describen métodos sobre cómo diagnosticar problemas de coincidencia de versiones.
Uso del Azure SDK para la herramienta de compilación de Java
El SDK de Azure para Java, introducido en Comenzar con el SDK de Azure y Apache Maven, ayuda a identificar problemas comunes. Se recomienda agregar esta herramienta de compilación al proyecto y ejecutarla agregando el destino de Maven al proceso de compilación normal. Con la configuración adecuada, puede identificar y resolver conflictos de dependencia de forma más proactiva, antes de que se conviertan en problemas en tiempo de ejecución.
Visualización de un árbol de dependencias
Ejecute o y muestre el árbol de dependencias completo de su aplicación, con números de versión. proporciona más información, pero puede ser engañosa. Para más información, consulte Árbol de dependencias de Apache Maven en la documentación de Maven. Para cada biblioteca sospechosa de que tiene un conflicto de versión, anote su número de versión y determine qué componentes dependen de ella.
La resolución de dependencias en entornos de desarrollo y producción puede funcionar de forma diferente. Los complementos apache Spark, Apache Flink, Databricks y IDE necesitan una configuración adicional para las dependencias personalizadas. También pueden traer sus propias versiones de Azure bibliotecas cliente o componentes comunes. Para obtener más información, consulte los artículos siguientes:
- Agrupación de las dependencias de la aplicación para Apache Spark
- Configuración del proyecto para Apache Flink
- Actualización correcta de una biblioteca de Maven en Databricks para Databricks
Para obtener más información sobre la resolución de conflictos en estos entornos, consulte la sección Creación de un archivo JAR fat más adelante en este artículo.
Configuración de Azure Functions
La versión de dependencia interna de Azure Functions (solo en ejecución Java 8) tiene prioridad sobre una proporcionada por el usuario. Esta dependencia provoca conflictos de versión, especialmente con Jackson, Netty y Reactor.
Para resolver este problema, establezca la variable de entorno en o . Asegúrese de actualizar las herramientas de función de Azure (v2 o v3) a la versión más reciente.
Nota:
Esta configuración solo se aplica a Azure Functions que ejecutan Java 8; las funciones que se ejecutan en Java 11 no necesitan ninguna configuración especial.
Configurar Apache Spark
El Azure SDK para Java admite varias versiones de Jackson, pero a veces pueden surgir problemas en función de las herramientas de compilación y su orden de resolución de dependencias. Un buen ejemplo de este problema es con Apache Spark, versión 3.0.0 y posteriores, que depende de Jackson 2.10. Aunque es compatible con el Azure SDK para Java, los desarrolladores a menudo descubren que se usa una versión más reciente de Jackson en su lugar, lo que da lugar a incompatibilidades. Para mitigar este problema, debe anclar una versión específica de Jackson (una compatible con Spark). Para obtener más información, consulte la sección Compatibilidad con varias versiones de Jackson de este artículo.
Si usa versiones anteriores de Spark o si otra biblioteca que usa requiere una versión incluso anterior de Jackson que el Azure SDK para Java no es compatible, siga leyendo este artículo para conocer los posibles pasos de mitigación.
Detección de la versión del entorno de ejecución de Jackson
En Azure Core 1.21.0, agregamos detección en tiempo de ejecución y mejores diagnósticos de la versión en tiempo de ejecución de Jackson.
Si ve (o cualquiera de sus subclases) relacionadas con la API de Jackson, compruebe el mensaje de la excepción para obtener información sobre la versión en tiempo de ejecución. Por ejemplo:
Busque registros de advertencias y errores de . Para obtener más información, vea Configuración del registro en el Azure SDK para Java. Por ejemplo:
Nota:
Compruebe que todos los paquetes de Jackson tienen la misma versión.
Para obtener la lista de paquetes usados por Azure SDK y las versiones de Jackson compatibles, consulte la sección Support para varias versiones de Jackson.
Mitigar problemas de incompatibilidad de versiones
En las secciones siguientes se describe cómo mitigar los problemas de coincidencia de versiones.
Uso de Azure SDK BOM
Utilice el Azure SDK BOM más reciente y no especifique las versiones de Azure SDK ni las versiones de sus dependencias en el archivo POM. Cuando corresponda, use el Azure Spring Boot BOM.
Las dependencias enumeradas en la Azure SDK BOM se prueban rigurosamente para evitar conflictos de dependencias.
Evitar dependencias innecesarias
Quite las dependencias si puede. A veces, una aplicación tiene dependencias en varias bibliotecas que proporcionan básicamente la misma funcionalidad. Estas dependencias innecesarias exponen las aplicaciones a vulnerabilidades de seguridad, conflictos de versión y costos de soporte técnico y mantenimiento.
Actualizar versiones de dependencia
Si cambiar a la Azure SDK boM más reciente no ayuda, identifique las bibliotecas que causan conflictos y los componentes que los usan. (Para obtener más información, consulte la sección Ver un árbol de dependencias anteriormente en este artículo). Intente actualizar a una versión más reciente, que protege contra vulnerabilidades de seguridad y, a menudo, aporta nuevas características, mejoras de rendimiento y correcciones de errores.
Evite degradar la versión de Azure SDK porque puede exponer la aplicación a vulnerabilidades y problemas conocidos.
Bibliotecas de sombra
A veces, no hay ninguna combinación de bibliotecas que funcionen juntas y el uso de bibliotecas en la sombra es el último recurso.
Nota:
El uso de sombreado tiene inconvenientes significativos: aumenta el tamaño del paquete y el número de clases en el classpath, hace que la navegación del código y la depuración sean difíciles, no reubica el código JNI, dificulta la reflexión y puede infringir licencias de código, entre otras cuestiones. Solo se debe usar después de que se agoten otras opciones.
El sombreado permite incluir dependencias dentro de un archivo JAR en tiempo de compilación y, a continuación, cambiar el nombre de los paquetes y actualizar el código de la aplicación para usar el código en la ubicación sombreada. El conflicto de dependencias en rombo ya no es un problema, porque hay dos copias diferentes de una dependencia. Puede sombrear una biblioteca que tenga una dependencia transitiva conflictiva o una dependencia de aplicación directa, como se describe en la lista siguiente:
-
Conflicto de dependencias transitivas: Por ejemplo, la biblioteca de terceros
Arequiere Jackson 2.9, que Azure SDKs no admiten y no es posible actualizarA. Cree un nuevo módulo, que incluya y ponga en la sombra (reubicar) la versión 2.9 de Jackson y, opcionalmente, otras dependencias de . - Conflicto de dependencias de la aplicación: la aplicación usa Jackson 2.9 directamente. Mientras trabaja para actualizar el código, puede sombrear y reubicar Jackson 2.9 en un nuevo módulo con clases de Jackson reubicadas en su lugar.
Nota:
La creación de un archivo fat-JAR con clases de Jackson reubicadas no resuelve el conflicto de versiones de estos ejemplos: solo fuerza una única versión en la sombra de Jackson.
Creación de un archivo fat-JAR
Los entornos como Databricks o Apache Spark tienen administración de dependencias personalizada y proporcionan bibliotecas comunes como Jackson. Para evitar conflictos con las bibliotecas proporcionadas, es posible que desee compilar un archivo JAR fat que contenga todas las dependencias. Para más información, consulte Complemento de sombra de Apache Maven. En muchos casos, la reubicación de las clases de Jackson () mitiga el problema. A veces, estos entornos también aportan su propia versión de los SDKs de Azure, por lo que pueda necesitar reubicar el com.azure espacio de nombres para solucionar conflictos de versiones.
Descripción de las versiones de dependencia compatibles
Para obtener información sobre dependencias específicas de y sus versiones, consulte azure-core en el Repositorio Central de Maven. En la tabla siguiente se muestran algunas consideraciones generales:
| Dependencia | Versiones compatibles |
|---|---|
| Jackson | 2.10.0 y versiones secundarias más recientes son compatibles. Para obtener más información, consulte la sección Compatibilidad con varias versiones de Jackson . |
| SLF4J | 1.7.* |
| netty-tcnative-boringssl-static | 2.0.* |
| netty-common | 4.1.* |
| núcleo de reactor | 3.X.*: los números de versión principal y secundaria deben coincidir exactamente con aquellos de los que depende su versión de . Para más información, consulte la directiva sobre entrada en desuso del proyecto Reactor. |
Compatibilidad con varias versiones de Jackson
El Azure SDK para Java admite el trabajo con una variedad de versiones de Jackson. La versión más baja admitida es Jackson 2.10.0. Las bibliotecas cliente del Azure SDK para Java ajustan su configuración y el uso de Jackson según la versión que se detecta en tiempo de ejecución. Este ajuste permite una mayor compatibilidad con versiones anteriores del marco spring, Apache Spark y otros entornos comunes. Las aplicaciones pueden degradar las versiones de Jackson (a la versión 2.10.0 o posterior) sin interrumpir Azure SDK para las bibliotecas cliente de Java.
Nota:
El uso de versiones anteriores de Jackson puede exponer aplicaciones a vulnerabilidades y problemas conocidos. Para obtener más información, consulte la lista de vulnerabilidades conocidas para las bibliotecas de Jackson.
Al anclar una versión específica de Jackson, asegúrese de hacerlo para todos los módulos usados por Azure SDK, que se muestran en la lista siguiente:
jackson-annotationsjackson-corejackson-databindjackson-dataformat-xmljackson-datatype-jsr310
Migración de Jackson a azure-json
Azure bibliotecas cliente para Java están en proceso de migración a azure-json, que no depende de ningún componente de terceros y ofrece primitivos compartidos, abstracciones y asistentes para JSON.
Los entornos como Apache Spark, Apache Flink y Databricks pueden traer versiones anteriores de que aún no dependen de . Como resultado, al usar versiones más recientes de bibliotecas de Azure en estos entornos, es posible que reciba errores similares a java.lang.NoClassDefFoundError: com/azure/json/JsonSerializable. Para mitigar este error, agregue una dependencia explícita en .
Pasos siguientes
Ahora que está familiarizado con los conflictos de versiones de dependencia y cómo solucionarlos, consulte Administración de dependencias para Java para obtener información sobre la mejor manera de evitarlos.