当前位置: 首页 > 科技观察

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

时间:2023-03-13 09:18:05 科技观察

JAR冲突问题的解决方法以及如何查看运行状态下加载的类在怎么看之前先说一下。当你开始意识到项目中有多个不同版本的jar包时,是因为这些异常:1.java.lang.NoSuchMethodException:在你自己的代码方法中调用了某个方法,因为其他版本的jar是loaded,这个版本没有这个方法。2.java.lang.NoClassDefFoundError:编译的时候没问题,但是运行的时候,因为加载的jar版本,没有这个类。3.java.lang.ClassNotFoundException:动态加载Class时,找不到类,因为要加载的jar版本不对。当你在本地运行正常,但是当你在服务器上发现这些错误时,你应该意识到它很可能是jar冲突(同一个依赖有多个版本)。这个问题往往有这样的表现:部署多个实例时,有的实例好,有的实例不好。查看加载的类和方法根据之前分析的异常类型,我们可以去运行站点确认当前加载的问题。这里我们可以使用阿里开源的Arthas工具。如果是第一次使用,先安装,然后运行如下:curl-Ohttps://arthas.aliyun.com/arthas-boot.jarjava-jararthas-boot.jarworkswell之后,会打印出当前运行的java应用程序,例如:[INFO]arthas-bootversion:3.4.6[INFO]Process40611alreadyusingport3658[INFO]Process40611alreadyusingport8563[INFO]Foundexistingjavaprocess,pleasechooseoneandinputtheserialnumberoftheprocess,eg:1.ThenhitENTER.*[1]:40611chapter4-3-0.0.1-SNAPSHOT.jar[2]:37786通过输入数字选择要查看的java应用,例如这里选择:1,输入chapter4-3-0.0.1-SNAPSHOT.jar。下面介绍两个重要的命令:第一个:sc命令,我们确认jar包下是否有对应的可能冲突的类。一些不同版本的包有不同的类,可以立即区分。例如,我们通过下面的命令查看com.didispace包下有哪些类:[arthas@40611]$sccom.didispace.*com.didispace.chapter43.Chapter43Applicationcom.didispace.chapter43.Chapter43Application$$EnhancerBySpringCGLIB$$8b82b194com.didispace.chapter43.UploadControllerAffect(row-cnt:3)costin6ms。第二个:sm命令,查看具体类有哪些方法。一些版本差异是某个方法已被删除。这时候我们就可以使用这个命令来查看了。例如,我们通过下面的命令查看com.didispace.chapter43.UploadController类下有哪些方法:[arthas@40611]$smcom.didispace.chapter43.UploadControllercom.didispace.chapter43.UploadController()Vcom。didispace.chapter43.UploadControllercreate(Lorg/springframework/web/multipart/MultipartFile;)Ljava/lang/String;com.didispace.chapter43.UploadControlleruploadPage()Ljava/lang/String;Affect(row-cnt:3)costin5ms。FindtheconflictandResolvingconflicts在确认是加载错误后,我们需要解决冲突。那么解决冲突我们需要做的就是找出冲突在哪里以及我们需要如何去除或强制找出版本冲突:使用Maven命令:mvn-Udependency: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:编译[信息]|||\-org.slf4j:jul-to-slf4j:jar:1.7.30:编译[信息]||+-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。核心:杰克逊核心:罐子:2.11.3:编译[信息]||+-com.fasterxml.jackson.datatype:杰克逊数据类型-jdk8:罐子:2.11.3:编译[信息]||+-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:编译[信息]||+-org.glassfish:jakarta.el:jar:3.0.3:编译[信息]||\-org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.41:编译[信息]|+-org.springframework:spring-web:jar:5.3.2:编译[信息]||\-org.springframework:spring-beans:jar:5.3.2:编译[信息]|\-org.springframework:spring-webmvc:jar:5.3.2:compile[INFO]|+-org.springframework:spring-aop:jar:5.3.2:compile[INFO]|+-org.springframework:spring-上下文: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[INFO]|||+-org.attoparser:attoparser:jar:2.0.5.RELEASE:compile解决版本冲突的方法主要有两种:1、通过上述命令找到不需要的版本后,导入依赖,使用exclusions来排除它,例如:groupId>xxxyyy2.必须在pom.xml中指定要使用的版本,这样优先级最高,会不引入其他版本要引入的版本。今天的分享就到这里了。希望对您有所帮助。如果您觉得本文有用,请转发并扩散!