Resolución de conflictos JAR

Hoy me encontré con un amigo del grupo y le pregunté que el programa en línea parece tener varios paquetes de Netty de diferentes versiones ¿Cómo veo cuál está cargado en la parte inferior?

Resolución de conflictos JAR Resolución de conflictos JAR

Antes de hablar sobre cómo mirar, hablemos de ello primero, cuando empiece a darse cuenta de que hay varias versiones de paquetes Jar en el proyecto, todo se debe a estas excepciones:

  • 1. java.lang.NoSuchMethodException: Se llamó a un método en mi código porque se cargan otras versiones del jar, y esta versión simplemente no tiene este método.
  • 2. java.lang.NoClassDefFoundError: es bueno cuando se compila, pero cuando se ejecuta, no existe tal clase debido a la versión jar cargada.
  • 3. java.lang.ClassNotFoundException: cuando una clase se carga dinámicamente, no se puede encontrar la clase porque el jar que se va a cargar no es la versión correcta.

Cuando ejecuta bien localmente, pero encuentra estos errores en el servidor, debe darse cuenta de que es probable que haya un conflicto de jar (hay varias versiones de la misma dependencia). Este problema a menudo se manifiesta de esta manera: cuando se implementan varias instancias, algunas son buenas, mientras que otras no.

Ver clases y métodos cargados

Según el tipo de anomalía analizada anteriormente, podemos ir al sitio de operación para confirmar el problema de carga actual.

Aquí podemos usar la herramienta Arthas de código abierto de Ali. Si la usa por primera vez, instálela y luego ejecútela de la siguiente manera:

curl -O https://arthas.aliyun.com/arthas-boot.jar 
java -jar arthas-boot.jar

Después de ejecutarse, imprimirá la aplicación Java que se esté ejecutando actualmente, como por ejemplo:

[INFO] arthas-boot versión: 3.4.6 
[INFO] El proceso 40611 ya usa el puerto 3658 
[INFO] El proceso 40611 ya usa el puerto 8563 
[INFO] Se encontró el proceso java existente, elija uno e ingrese el número de serie del proceso, por ejemplo : 1. Luego presione ENTER. 
* [1]: 40611 capítulo4-3-0.0.1-SNAPSHOT.jar 
  [2]: 37786

Seleccione la aplicación java que desea ver ingresando el número, por ejemplo, seleccione aquí: 1, ingrese capítulo4-3-0.0.1-SNAPSHOT.jar.

Aquí hay dos comandos importantes :

El primero: comando sc , confirmemos si hay una clase correspondiente en el paquete jar que puede entrar en conflicto. Algunas versiones diferentes de paquetes tienen diferentes clases, que se pueden distinguir de inmediato.

Por ejemplo, con el siguiente comando, podemos verificar qué clases hay en el paquete com.didispace:

[Arthas @ 40611] $ sc com.didispace *. 
com.didispace.chapter43.Chapter43Application 
com.didispace.chapter43.Chapter43Application $$ $$ EnhancerBySpringCGLIB 8b82b194 
com.didispace.chapter43.UploadController 
Afectar (fila-CNT: 3) el costo de 6 milisegundo.

El segundo: comando sm, para ver qué métodos tiene una clase específica. Algunas diferencias de versión son que se ha eliminado cierto método. En este momento, podemos usar este comando para verificar.

Por ejemplo, a través del siguiente comando, verifiquemos qué métodos están disponibles en la clase com.didispace.chapter43.UploadController:

[arthas @ 40611] $ sm com.didispace.chapter43.UploadController 
com.didispace.chapter43.UploadController () V 
com.didispace.chapter43.UploadController create (Lorg / springframework / web / multipart / MultipartFile;) Ljava / lang / String; 
com.didispace.chapter43.UploadController uploadPage () Ljava / lang / String; 
Afecto (row-cnt: 3) costo en 5 ms.

Encuentra y resuelve conflictos

Después de confirmar que se trata de un error de carga, tenemos que resolver el conflicto. Entonces, lo que tenemos que hacer para resolver el conflicto es averiguar dónde está y qué queremos eliminar o forzar.

El método para averiguar el conflicto de versiones: Utilice el comando de Maven: mvn -U dependency: tree -Dverbose.

Después de ejecutar el comando, todas las dependencias se enumerarán en la consola en forma de árbol, y luego se buscarán los paquetes en conflicto para ver qué dependencias se incorporan (la búsqueda en IDEA lo resaltará, lo que facilitará su aparición).

[INFO] com.didispace: capítulo4-3: jar: 0.0.1-SNAPSHOT 
[INFO] + - org.springframework.boot: spring-boot-starter-web: jar: 2.4.1: compilar 
[INFO] | + - org.springframework.boot: spring-boot-starter: jar: 2.4.1: compilar 
[INFO] | | + - org.springframework.boot: spring-boot: jar: 2.4.1: compilar 
[INFO] | | + - org.springframework.boot: spring-boot-autoconfigure: jar: 2.4.1: compile 
[INFO] | | + - org.springframework.boot: spring-boot-starter-logging: jar: 2.4.1: compilar 
[INFO] | | | + - ch.qos.logback: logback-classic: jar: 1.2.3: compile 
[INFO] | | | | \ - ch.qos.logback: logback-core: jar: 1.2.3: compile 
[INFO] | | | + - org.apache.logging.log4j: log4j-to-slf4j: jar: 2.13.3: compilar 
[INFO] | | | | \ - org.apache.logging.log4j: log4j-api: jar: 2.13.3: compile 
[INFO] | | | \ - org.slf4j: jul-to-slf4j: jar: 1.7.30: compilar
[INFO] | | + - jakarta.annotation: jakarta.annotation-api: jar: 1.3.5: compile 
[INFO] | | \ - org.yaml: snakeyaml: jar: 1.27: compile 
[INFO] | + - org.springframework.boot: spring-boot-starter-json: jar: 2.4.1: compilar 
[INFO] | | + - com.fasterxml.jackson.core: jackson-databind: jar: 2.11.3: compile 
[INFO] | | | + - com.fasterxml.jackson.core: jackson-annotations: jar: 2.11.3: compile 
[INFO] | | | \ - com.fasterxml.jackson.core: jackson-core: jar: 2.11.3: compile 
[INFO] | | + - com.fasterxml.jackson.datatype: jackson-datatype-jdk8: jar: 2.11.3: compile 
[INFO] | + - org.springframework.boot: spring-boot-starter-tomcat: jar: 2.4.1: compilar 
[INFO] | | + - com.fasterxml.jackson.datatype: jackson-datatype-jsr310: jar: 2.11.3: compilar
[INFO] | | \ - com.fasterxml.jackson.module: nombres-de-parámetros-módulo-jackson: jar: 2.11.3: compilar 
[INFO] | \ - org.springframework: spring-expression: jar: 5.3.2: compilar
[INFO] | | + - org.apache.tomcat.embed: tomcat-embed-core: jar: 9.0.41: compile 
[INFO] | | + - org.glassfish: jakarta.el: jar: 3.0.3: compilar 
[INFO] | | \ - org.apache.tomcat.embed: tomcat-embed-websocket: jar: 9.0.41: compile 
[INFO] | + - org.springframework: spring-web: jar: 5.3.2: compile 
[INFO] | | \ - org.springframework: spring-beans: jar: 5.3.2: compile 
[INFO] | \ - org.springframework: spring-webmvc: jar: 5.3.2: compilar 
[INFO] | + - org.springframework: spring-aop: jar: 5.3.2: compile 
[INFO] | + - org.springframework: spring-context: jar: 5.3.2: compilar 
[INFO] + - org.springframework.boot: spring-boot-starter-thymeleaf: jar: 2.4.1: compilar 
[INFO] | + - org.thymeleaf: thymeleaf-spring5: jar: 3.0.11.RELEASE: compilar
[INFO] | | + - org.thymeleaf: thymeleaf: jar: 3.0.11.RELEASE: compile 
[INFO] | | | + - org.attoparser: attoparser: jar: 2.0.5.RELEASE: compilar

Hay dos formas principales de resolver los conflictos de versiones:

  • 1. Después de encontrar la versión no deseada a través del comando anterior, use exclusiones para excluirla entre las dependencias importadas
  • 2. Obligatorio especificar la versión que se utilizará en pom.xml, para que tenga la máxima prioridad y no introduzca la versión que traerán otras versiones.

Supongo que te gusta

Origin blog.csdn.net/yaxuan88521/article/details/113748857
Recomendado
Clasificación