Haga un buen uso de estas técnicas para resolver fácilmente los conflictos de paquetes de Maven Jar

Autor: Platinum Poseidon

Enlace original: https://www.cnblogs.com/bryan31/p/13408479.html

Prefacio

Todos deben haber encontrado el problema de conflicto del paquete Jar de Maven en el proyecto. Los escenarios comunes son:

NoSuchMethodError y ClassNotFoundException se notifican cuando se ejecutan localmente. Obviamente, existe este paquete Jar en la dependencia. ¿Por qué no puede funcionar? ?

El proyecto define claramente una determinada versión de paquete jar como 2.0.2, ¿cómo puede convertirse en 2.5.0 después del empaquetado? ?

El proyecto A importó el paquete xxx.jar y funcionó bien, y el proyecto B también importó xxx.jar y se informó de un error. . ¿Hay algún problema con el proyecto B o el paquete xxx.jar? ?

El entorno local y el entorno de prueba están funcionando bien. Cuando se trata de producción, se informa de un montón de NoSuchMethodErrors. ¿Hay algún problema con mi personaje o el entorno de producción? ?

Si este problema es investigado por estudiantes que no están familiarizados con el mecanismo de dependencia de maven, será un dolor de cabeza.

Además, maven se basa en proyectos mal estructurados y el riesgo de introducir nuevos paquetes Jar también es enorme. Los más pequeños afectan el rendimiento, mientras que los más grandes provocan excepciones en la versión de producción y en el tiempo de ejecución.

De hecho, las causas fundamentales de los problemas anteriores provienen del conflicto del paquete Jar de Maven y del uso inadecuado de la entrega de dependencias. En este artículo analizaré los siguientes 3 contenidos:

  • Análisis del principio de confiar en la entrega y el principio de causar conflicto en el paquete Jar
  • Varias técnicas simples para localizar conflictos y resolver conflictos de paquetes Jar
  • Cómo escribir un archivo POM con dependencias limpias

Principio de transferencia de dependencia

Casi todos los conflictos de paquetes Jar están relacionados con el principio de transferencia de dependencia, así que primero hablemos del principio de transferencia de dependencia en Maven:

El primer principio del camino más corto

Si se introducen dos paquetes Jar A y B, ambos dependen transitivamente del paquete Jar Z:

A -> X -> Y -> Z (2.5)

B -> X -> Z (2.0)

De hecho, la versión que finalmente entró en vigor fue la Z (2.0). Porque su camino es más corto. Si hago referencia al paquete Z (3.0) localmente, la versión 3.0 es efectiva. La misma razon.

Primero declare el principio de prioridad

Si la longitud de la ruta es la misma, se prefiere la primera declarada.

A -> Z (3,0)

B -> Z (2,5)

Aquí, A es el primero en declarar, por lo que el Z pasado elige usar la versión 3.0.

El principio del conflicto del paquete Jar

Supongamos que nuestro proyecto se basa en dos paquetes Jar, A y B. Y A y B tienen cada uno las siguientes dependencias transitivas

A -> X -> Z (2.0)

B -> X -> Y -> Z (2.5)

Luego, el paquete Z entra en conflicto en el sistema final, y las dos versiones de 2.0 y 2.5 entran en conflicto. Pero solo una versión del paquete Z depende de la ruta de clases. De acuerdo con el primer principio de dependencia transitiva del camino más corto , la dependencia final debería ser la versión 2.0.

Si el nuevo método en la versión 2.5 del paquete Z se usa en el paquete Y, cuando se ejecuta esta lógica. Informará NoSuchMethodError. Debido a que originalmente se basó en la versión 2.5, pero debido al conflicto del paquete Jar, Maven eligió la versión 2.0 y no había ningún método nuevo en la versión 2.0, lo que provocó un error.

Pero debe tenerse en cuenta que no todos los conflictos causarán un funcionamiento anormal. Por el contrario, la mayoría de los proyectos de la compañía tendrán algunos conflictos de paquetes Jar, pero no causan problemas de tiempo de ejecución.

Esto se debe a que se pueden ejecutar muchos paquetes Jar que son dependientes transitivamente, ya sea la versión 2.0 o la versión 2.5.

Solo la versión superior del paquete Jar no es compatible con versiones anteriores, o algunas API nuevas que no están disponibles en la versión inferior pueden causar este problema

Conflicto de posicionamiento

IDEA proporciona un artefacto de análisis de dependencia maven: Maven Helper

Haga un buen uso de estas técnicas para resolver fácilmente los conflictos de paquetes de Maven Jar

 

Utilice este complemento para mostrar todos los árboles de dependencia y los conflictos del proyecto.

Haga un buen uso de estas técnicas para resolver fácilmente los conflictos de paquetes de Maven Jar

 

La parte resaltada en rojo aquí indica que el paquete Jar tiene un conflicto. Seleccione este paquete jar, puede ver el origen del conflicto entre las dos versiones.

El ejemplo de la figura anterior muestra que el paquete Jar de cruiser-client tiene dos dependencias transitivas, que son la versión 2.5.0 y la versión 4.0.1. La descripción del conflicto es:

omitido por conflicto con 2.5.0. Omitido por conflicto con 2.5.0

El nivel específico también está claro a la derecha, por lo que maven finalmente eligió la versión 2.5.0 según el principio de la ruta más corta , y se ignoró la versión 4.0.1.

En este momento, algunos estudiantes preguntarán: Puedo usar Maven Helper para ubicar el entorno local, ¿qué pasa con el entorno de preproducción o producción? Sin IDEA, ¿cómo localizar los detalles del conflicto?

Puede usar el comando mvn para resolver:

dependencia de mvn: árbol -Dverbose

No omita el parámetro -Dverbose aquí, de lo contrario, los paquetes ignorados no se mostrarán

Haga un buen uso de estas técnicas para resolver fácilmente los conflictos de paquetes de Maven Jar

 

De hecho, la línea de comando mvn es igual de fácil de usar. Muy claro.

Varias técnicas prácticas para resolver conflictos de paquetes Jar

Exclusión

Aún así, el ejemplo anterior, ahora 2.5.0 es efectivo, si desea que surta efecto 4.0.1. Simplemente haga clic en excluir en 2.5.0.

Haga un buen uso de estas técnicas para resolver fácilmente los conflictos de paquetes de Maven Jar

 

Bloqueo de versión

Si se pasan muchas dependencias del paquete Jar A, hay muchas versiones involucradas, pero solo desea especificar una versión. Es demasiado engorroso excluir uno por uno mediante el método de exclusión, y la exclusión se reflejará en el archivo pom. Si hay demasiados, también afectará la limpieza del código y la experiencia de lectura.

En este momento, debe utilizar el método de bloqueo de versión

¿Qué es el bloqueo de versión? El proyecto de una empresa generalmente tiene un pom principal. Solo necesita especificar qué versión desea especificar en el POM principal de su proyecto (por supuesto, también se puede definir en este proyecto) de la siguiente manera: (O tome el ejemplo anterior, especifique la versión 4.0.1)

<dependencyManagement>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-client</artifactId>
        <version>4.0.1</version>
    </dependency>
</dependencyManagement>

El método de la versión bloqueada puede romper los dos principios de la transferencia de dependencia, con la máxima prioridad

Una vez que la versión está bloqueada, el árbol de dependencias es:

Haga un buen uso de estas técnicas para resolver fácilmente los conflictos de paquetes de Maven Jar

 

Todos están unificados a 4.0.1 Hay una ventaja de bloquear la versión: el bloqueo de la versión no excluye el paquete Jar, y muestra todos los paquetes Jar inconsistentes en una versión unificada, que es más amigable al leer el código. No tiene que soportar muchas etiquetas de exclusión.

Cómo escribir un archivo POM con dependencias limpias

Soy una persona con una limpieza de código suave, por lo que incluso las dependencias del archivo pom quieren estar limpias y ordenadas. Cómo escribir un POM limpio, el autor cree que hay varios consejos a los que prestar atención:

  • Intente definir <dependencyManagement> en el POM principal para administrar algunas versiones dependientes de este proyecto, de modo que ciertos conflictos se puedan resolver en gran medida
  • Si es un paquete Jar proporcionado a otras personas en quien confiar, intente no pasar paquetes Jar innecesarios tanto como sea posible
  • Utilice el comando mvn dependency: analyse-only para detectar las dependencias que se declaran pero no se utilizan. Si algunas de ellas las declara usted mismo, intente eliminarlas
  • Utilice el comando mvn dependency: analyse-duplicate para analizar las dependencias definidas repetidamente y limpiar esas dependencias definidas repetidamente

Al final

De hecho, debe haber muchas dependencias en grandes proyectos. Pero no importa cuán complicada sea la dependencia, no tema verla. Con solo unos pocos principios y un análisis cuidadoso, todas las dependencias son rastreables.

Si estas dependencias transitivas se gestionan bien, sus costes de mantenimiento pueden reducirse considerablemente. Si no te las arreglas bien, cada uno de estos niños salvajes puede ser el fusible para el próximo NoSuchMethodError.

Supongo que te gusta

Origin blog.csdn.net/GYHYCX/article/details/108783867
Recomendado
Clasificación