全国服务热线:400-6263-721

位置:南宁达内IT教育培训学校 > 学校动态 > java依赖冲突问题定位技巧

java依赖冲突问题定位技巧

来源:南宁达内IT教育培训学校时间:2022/8/16 17:39:37

  发生依赖冲突主要表现为系统启动或运行中会发生异常,99%表现为三种NoClassDefFoundError、ClassNotFoundException、NoSuchMethodError。下面逐一讲解一下定位技巧。

  1 NoClassDefFoundError、ClassNotFoundException排查定位步骤

  STEP1、发生NoClassDefFoundError首先要看完整异常栈,确认是否是静态代码块发生异常,静态代码块发生异常堆栈与jar包冲突有很明显的区别,出现"Could not initialize"、"Caused by: ..."关键字一般是静态代码块发生异常导致类加载失败:

  java.lang.NoClassDefFoundError: Could not initialize class testing.User at testing.Test.main(Test.java:23)Caused by: java.lang.RuntimeException: UserId Not found at testing.User.getUserId(Test.java:41) at testing.User.(Test.java:35) ... 1 more

  因为静态代码块发生异常导致NoClassDefFoundError,修改静态代码块避免抛出异常即可。如果不是静态代码块发生异常导致的问题,继续下一步。

  STEP2、如果不是静态代码块发生异常导致加载失败,异常message关键字中会明确显示缺失的类名称,

  java.lang.NoClassDefFoundError: org/apache/commons/lang/CharUtils at testing.Test.main(Test.java:19)

  STEP3、在IDEA中(快捷键Ctrl+N)查找异常栈中提示缺失的类在哪些版本的jar包中有,如上例中的org.apache.commons.lang.CharUtils

  STEP4、查看应用部署机器上应用lib包目录下(一般是/home/admin/union-uc/target/${projectName}/lib或union-pub/target/${projectName}.war/WEB-INF/lib)是否存在上一步骤中查出对应版本的jar包,以上情况一般是因为此时应用依赖的是低版本jar包,而jar包中又没有冲突的类,绝大部分情况下NoClassDefFoundError、ClassNotFoundException定位确认都是因为maven依赖仲裁较终采纳的jar包版本与运行时需要的不一致导致。

  2 NoSuchMethodError排查到位步骤

  STEP1、发生NoSuchMethodError,异常堆栈日志核心片段(异常栈中处于栈底的片段,见过很多同学发生异常乱翻一通,那样毫无意义,要有目的的翻关键地方,不要乱翻)会明确显示具体是哪个类,缺失了哪个方法,异常堆栈核心片段:

  Caused by: java.lang.NoSuchMethodError: org.springframework.beans.factory.support.DefaultListableBeanFactory.getDependencyComparator()Ljava/util/Comparator; at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:190) at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.registerComponents(ComponentScanBeanDefinitionParser.java:150) at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.parse(ComponentScanBeanDefinitionParser.java:86) at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:73)

  首先需确认JVM中当前加载的缺失方法类,如上"org.springframework.beans.factory.support.DefaultListableBeanFactory"类到底来自哪个jar包,目前较的办法:

  外部环境容器下,或者某些容器版本过低不支持Arthas在线诊断的情况下,可以通过在JVM启动参数中增加" -XX:+TraceClassLoading",然后重新启动系统,在系统工程日志中即可看到JVM加载类的信息。从中即可找到JVM是从哪个jar包中加载的。

  STEP2、在IDEA中(快捷键Ctrl+N)查找异常栈中提示缺失的类在哪些版本的jar包中有

  然后依次查看各版本jar包中冲突类的源码,工程中部分jar打包时附带了源码包可直接看到源码,不带源码的需要用IDEA插件(推荐jad)反编译一下。然后依次搜寻各个jar包中的冲突类,搜寻步是点击上图中某个版本类,在IDEA中查找类级次关系(快捷键Ctrl+H),

  然后在冲突类及所有冲突类的父类源码中找到NoSuchMethodError异常信息中描述缺失的方法,以上例子中就是"getDependencyComparator()Ljava/util/Comparator"。

  上例中通过搜寻可以发现spring-beans-3.2.1.RELEASE.jar,spring-2.5.6.SEC03.jar两个版本DefaultListableBeanFactory类及父类中没有"getDependencyComparator()Ljava/util/Comparator"方法,spring-beans-4.2.4.RELEASE.jar,spring-beans-4.3.5.RELEASE.jar两个版本DefaultListableBeanFactory类中有缺失的"getDependencyComparator()Ljava/util/Comparator"方法。

  STEP3、查看应用部署机器上应用lib包目录下(一般是/home/admin/union-uc/target/${projectName}/lib或union-pub/target/${projectName}.war/WEB-INF/lib)下,找到相关jar包的版本

  致此定位问题根本原因是应用启动时加载"org.springframework.beans.factory.support.DefaultListableBeanFactory"类未加载到运行时预期所需的spring-beans-4.3.5.RELEASE.jar版本,而是加载了spring-2.5.6.SEC03.jar导致。

  按照以上流程步骤,基本99%的依赖冲突都可以定位到根本原因。定位到原因后如何解决冲突呢?事实上有些时候解决冲突远没有内网上很多帖子描述的"mvn dependency:tree"一下,排排jar那么简单。具体细节请继续看下一章节。

领取试听课
每天限量名额,先到先得

尊重原创文章,转载请注明出处与链接:http://www.peixun360.com/1658/news/555034/违者必究! 以上就是南宁达内IT教育培训学校 小编为您整理 java依赖冲突问题定位技巧的全部内容。

温馨提示:提交留言后老师会第一时间与您联系!热线电话:400-6263-721