JAR冲突问题的解决以及运行状态下如何查看加载的类

简介: JAR冲突问题的解决以及运行状态下如何查看加载的类

今天碰到群里小伙伴问,线上程序好像有多个不同版本的Netty包,怎么去看到底加载了哪一个?

在说如何看之前,先来说说,当你开始意识到项目里有多个不同版本的Jar包,都是因为遇到了这几个异常:

  1. java.lang.NoSuchMethodException:自己代码中调用了某个方法,因为加载了其他版本的jar,这个版本正好没这个方法。
  2. java.lang.NoClassDefFoundError:编译时候是好的,但是运行的时候,因为加载的jar版本问题,没有这个类。
  3. java.lang.ClassNotFoundException:在动态加载某个Class的时候,因为要加载的jar不是正确的版本,而导致找不到这个类。

当你在本地运行ok,但到服务器上发现出现这些错误的时候,就要意识到很可能是jar冲突了(有相同依赖存在多个版本)。这个问题往往也会有这样的表现:多实例部署的时候,有的实例是好的,有的实例则不行。

查看加载的类和方法

根据之前分析的异常种类,我们可以去运行中的现场确认当前加载的问题。

这里我们可以使用阿里开源的Arthas工具,如果第一次用,那么按下面操作先安装再运行:

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

运行好之后,会打印出当前运行着的java应用,比如:

[INFO] arthas-boot version: 3.4.6
[INFO] Process 40611 already using port 3658
[INFO] Process 40611 already using port 8563
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 40611 chapter4-3-0.0.1-SNAPSHOT.jar
  [2]: 37786

通过输入编号选择要查看的java应用,比如这里选择:1,进入到chapter4-3-0.0.1-SNAPSHOT.jar中去。

下面介绍两个重要命令:

第一个:sc命令,我们确认一下可能冲突的jar包下面,是否有对应的class。有些不同版本包下class就不一样,马上就可以分辨出来。

比如,通过下面的命令,我们查看一下com.didispace包下有什么类:

[arthas@40611]$ sc com.didispace.*
com.didispace.chapter43.Chapter43Application
com.didispace.chapter43.Chapter43Application$$EnhancerBySpringCGLIB$$8b82b194
com.didispace.chapter43.UploadController
Affect(row-cnt:3) cost in 6 ms.

第二个:sm命令,查看具体某个类有哪些方法。有的版本差异就是去掉了某个方法,这个时候我们就可以通过这个命令来查看。

比如,通过下面的命令,我们查看一下com.didispace.chapter43.UploadController类下有些什么方法:

[arthas@40611]$ sm com.didispace.chapter43.UploadController
com.didispace.chapter43.UploadController <init>()V
com.didispace.chapter43.UploadController create(Lorg/springframework/web/multipart/MultipartFile;)Ljava/lang/String;
com.didispace.chapter43.UploadController uploadPage()Ljava/lang/String;
Affect(row-cnt:3) cost in 5 ms.

找到冲突并解决冲突

在确认完是加载错误的情况下,我们要去解决冲突。那么解决冲突要做的就是找到到底哪里冲突了以及我们要去除或者强制

找出版本冲突的方法:使用Maven命令:mvn -U dependency:tree -Dverbose

命令执行之后,会在控制台以树状形式列出所有依赖内容,然后通过搜索的方式查找冲突的包,看看都是从哪个依赖中带进来的(在IDEA中搜索会高亮,更容易找到)。

[INFO] com.didispace:chapter4-3:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.4.1:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:2.4.1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:2.4.1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.4.1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.4.1:compile
[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:compile
[INFO] |  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.13.3:compile
[INFO] |  |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.30:compile
[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:compile
[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] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.11.3:compile
[INFO] |  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.11.3:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.4.1:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.41:compile
[INFO] |  |  +- org.glassfish:jakarta.el:jar:3.0.3:compile
[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:compile
[INFO] |     +- org.springframework:spring-aop:jar:5.3.2:compile
[INFO] |     +- org.springframework:spring-context:jar:5.3.2:compile
[INFO] |     \- org.springframework:spring-expression:jar:5.3.2:compile
[INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:2.4.1:compile
[INFO] |  +- org.thymeleaf:thymeleaf-spring5:jar:3.0.11.RELEASE:compile
[INFO] |  |  +- org.thymeleaf:thymeleaf:jar:3.0.11.RELEASE:compile

解决版本冲突的方式主要两种:

  1. 通过上面的命令找到不需要的版本之后,在引入的依赖中,使用exclusions将其排除,比如下面这样:
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jdbc</artifactId>
  <exclusions>
    <exclusion>
      <groupId>xxx</groupId>
      <artifactId>yyy</artifactId>
    </exclusion>
  </exclusions>
</dependency>
  1. pom.xml中强制指定要使用的版本,这样这个优先级最高,就不会引入其他版本要带进来的版本了。

好了,今天的分享到这里结束了,希望对你有所帮助。如果您觉得本文有用,欢迎转发扩散!

目录
相关文章
|
5月前
|
Java Spring
Spring boot 运行服务jar外配置配置文件方式总结
Spring boot 运行服务jar外配置配置文件方式总结
966 0
|
4月前
|
Java 应用服务中间件 Spring
为什么SpringBoot的 jar 可以直接运行?
SpringBoot的 jar 可以直接运行的原因
435 2
|
4月前
|
Java Linux Maven
java依赖冲突解决问题之容器加载依赖jar包如何解决
java依赖冲突解决问题之容器加载依赖jar包如何解决
|
2月前
|
存储 数据可视化 Java
震惊!如何在linux下部署项目,部署/运行jar包 超详细保姆级教程!
如何在Linux系统下部署和运行Java项目jar包,包括传输文件到Linux、使用nohup命令运行jar包、查看端口状态、杀死进程和查看项目运行状态,以及如何解决“没有主清单属性”的错误。
596 1
震惊!如何在linux下部署项目,部署/运行jar包 超详细保姆级教程!
|
2月前
|
Java Windows
如何在windows上运行jar包/JAR文件 如何在cmd上运行 jar包 保姆级教程 超详细
本文提供了一个详细的教程,解释了如何在Windows操作系统的命令提示符(cmd)中运行JAR文件。
1029 1
|
4月前
|
Java Maven 容器
Maven使用IDEA自带工具打包,同时将lib下的jar包打入,双击jar包可直接运行
使用IntelliJ IDEA的Artifacts功能,可以将项目依赖的第三方jar包打包进jar文件中,实现双击jar包即可直接运行。
Maven使用IDEA自带工具打包,同时将lib下的jar包打入,双击jar包可直接运行
|
4月前
|
SQL 前端开发 Java
在IDEA中使用Maven将SpringBoot项目打成jar包、同时运行打成的jar包(前后端项目分离)
这篇文章介绍了如何在IntelliJ IDEA中使用Maven将Spring Boot项目打包成可运行的jar包,并提供了运行jar包的方法。同时,还讨论了如何解决jar包冲突问题,并提供了在IDEA中同时启动Vue前端项目和Spring Boot后端项目的步骤。
在IDEA中使用Maven将SpringBoot项目打成jar包、同时运行打成的jar包(前后端项目分离)
|
4月前
|
前端开发 Java 编译器
classpath中存在多个jar存在同限定名的class classloader会如何加载
总之,合理组织类路径和使用现代化的构建工具,可有效避免类加载冲突,保证应用的稳定运行。
143 8
|
4月前
|
Java Maven C++
【Azure Developer】记录一次使用Java Azure Key Vault Secret示例代码生成的Jar包,单独运行出现 no main manifest attribute, in target/demo-1.0-SNAPSHOT.jar 错误消息
【Azure Developer】记录一次使用Java Azure Key Vault Secret示例代码生成的Jar包,单独运行出现 no main manifest attribute, in target/demo-1.0-SNAPSHOT.jar 错误消息
|
4月前
|
Java Spring
【Azure 应用服务】一个 App Service 同时部署运行两个及多个 Java 应用程序(Jar包)
【Azure 应用服务】一个 App Service 同时部署运行两个及多个 Java 应用程序(Jar包)

热门文章

最新文章