项目maven依赖冲突问题排查思路

前言

先介绍下接口字段校验的框架Java服务端接口参数校验框架——hibernate-validator使用
我们项目采用的springboot,在web依赖中已经封装了该框架,如下

在这里插入图片描述
所以可以直接使用,无需再引入其他依赖。

这里仅贴出一段在项目中用到的、和问题有关的代码,如下ValidationUtils

private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

 public static <T> void validateProperties(T obj, String... propertyNames) throws GlobalException {
       if (propertyNames.length > 0) {
           for (String propertyName : propertyNames) {
               validateProperty(obj, propertyName);
           }
       }
   }

validateProperties即是用于校验的方法。

问题场景

在接口中用到了上述validateProperties方法。
项目启动过程没有问题,结果在调用接口时,抛出如下异常

Caused by: javax.validation.ValidationException: HV000183: Unable to
initialize ‘javax.el.ExpressionFactory’. Check that you have the EL
dependencies on the classpath, or use ParameterMessageInterpolator
instead at
org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.buildExpressionFactory(ResourceBundleMessageInterpolator.java:123)
at
org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.(ResourceBundleMessageInterpolator.java:47)
at
org.hibernate.validator.internal.engine.ConfigurationImpl.getDefaultMessageInterpolator(ConfigurationImpl.java:494)
at
org.hibernate.validator.internal.engine.ConfigurationImpl.getDefaultMessageInterpolatorConfiguredWithClassLoader(ConfigurationImpl.java:670)
at
org.hibernate.validator.internal.engine.ConfigurationImpl.getMessageInterpolator(ConfigurationImpl.java:418)
at
org.hibernate.validator.internal.engine.ValidatorFactoryImpl.(ValidatorFactoryImpl.java:187)
at
org.hibernate.validator.HibernateValidator.buildValidatorFactory(HibernateValidator.java:38)
at
org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:386)
at
javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:103)
at com.sf.iotp.util.ValidationUtils.(ValidationUtils.java:15)
… 58 common frames omitted

问题分析

1.分析异常链路,找到报错代码

首先分析异常链。发现最初是初始化ValidationUtils类,最后调用到ResourceBundleMessageInterpolator类的buildExpressionFactory方法。

在这里插入图片描述

2.断点跟进

由上图还无法得知为什么最后会抛出异常,所以我们可以使用断点跟进,看具体是哪一行代码导致的。
最后得知,是由于下面红框代码返回false。
在这里插入图片描述
进入该方法查看,发现找不到ExpressionFactory类的newInstance方法,导致进入catch语句,返回false

在这里插入图片描述

为什么这里会找不到方法呢?

3.对比其他正常项目

还好,我们另一个正常运行的项目也用到了该校验框架,我们可以对比下两边项目的差异。

正常项目的ExpressionFactory类:
是在tomcat-embed-el包的javax.el包

在这里插入图片描述

报错项目的ExpressionFactory类:

是在jsp-api包的javax.el包
在这里插入图片描述
可以看到都是javax.el包,但是它们的父包是不一样的。

那报错的项目为什么没有在tomcat-embed-el包里寻找ExpressionFactory呢?是因为没有这个包吗?

继续分析发现,tomcat-embed-el包是springboot的web依赖,两边的项目都是有的。
在这里插入图片描述

既然两边都有,那就说明是由于报错的项目多引入了jsp-api包,导致运行时去这个包寻找了。

所以,只要知道在哪里引入了这个包,就能基本解决问题了。

4.分析依赖树,看是哪里引入了jsp-api包

项目这么多依赖,怎么定位是哪里引入了jsp-api包?于是,maven依赖树命令派上用场了。

我们在报错项目的pom文件所在目录下执行

mvn dependency:tree

然后去搜索关键字即可,此处运行结果就不再展示了

问题解决

反之jsp-api也不是我们项目需要的代码,所以直接去除jsp-api相关依赖

 <dependency>
       <groupId>/*......*/</groupId>
        <artifactId>portal-access</artifactId>
        <version>4.8-SNAPSHOT</version>
        <exclusions>
            <exclusion>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
            </exclusion>
        </exclusions>
 </dependency>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值