解决Could not initialize class org.hibernate.validator.internal.engine.ConfigurationImpl

最近在中台组件一次版本迭代中,网关组件升级版本后其它业务线集成网关组件后项目启动失败,

出现了

Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.internal.engine.ConfigurationImpl
    at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:33) ~[hibernate-validator-6.0.16.Final.jar:6.0.16.Final]
    at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:296) ~[validation-api-2.0.1.Final.jar:na]
    at org.springframework.boot.validation.MessageInterpolatorFactory.getObject(MessageInterpolatorFactory.java:53) ~[spring-boot-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.boot.context.properties.ConfigurationPropertiesJsr303Validator$Delegate.<init>(ConfigurationPropertiesJsr303Validator.java:69) ~[spring-boot-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.boot.context.properties.ConfigurationPropertiesJsr303Validator.<init>(ConfigurationPropertiesJsr303Validator.java:42) ~[spring-boot-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.getJsr303Validator(ConfigurationPropertiesBinder.java:109) ~[spring-boot-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.getValidators(ConfigurationPropertiesBinder.java:99) ~[spring-boot-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.bind(ConfigurationPropertiesBinder.java:80) ~[spring-boot-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:107) ~[spring-boot-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:93) ~[spring-boot-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:416) ~[spring-beans-5.0.13.RELEASE.jar:5.0.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1686) ~[spring-beans-5.0.13.RELEASE.jar:5.0.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573) ~[spring-beans-5.0.13.RELEASE.jar:5.0.13.RELEASE]
    ... 78 common frames omitted


Process finished with exit code 1

这种错误。

开始排查问题:

首先根据错误提示,看了一下组件源码中org.hibernate.validator.internal.engine.ConfigurationImpl这个类是否存在,

在hibernate-valifator-6.0.16-Final包中可以看到这个class文件。

继续排查是否打包的过程中出现错误致使该文件不存在,业务线自己排查fatJar包中有hibernate-valifator的包并且版本一致,

而且没有其它版本的hibernate-valifator的包,不存在多个版本依赖冲突的问题。

 

开始源码探索之路:

打开ConfigurationImpl源码,看里面是否有某些类没有被依赖到造成该类本身不能被实例化,在ConfigurationImpl中没有发现问题。

但是其中有一段代码:

private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );

为什么关注它?因为中台所有技术组件都按照要求排除了所有的日志实现,只保留slf4j本身的API去供技术组件使用,

而这个LoggerFactory并不是slf4j本身的,是属于hibernate本身的。打开之后发现:

package org.hibernate.validator.internal.util.logging;

import java.lang.invoke.MethodHandles.Lookup;

import org.jboss.logging.Logger;

/**
 * @author Hardy Ferentschik
 * @author Kevin Pollet &lt;kevin.pollet@serli.com&gt; (C) 2012 SERLI
 * @author Sanne Grinovero
 */
public final class LoggerFactory {

    public static Log make(final Lookup creationContext) {
        final String className = creationContext.lookupClass().getName();
        return Logger.getMessageLogger( Log.class, className );
    }

    // private constructor to avoid instantiation
    private LoggerFactory() {
    }
}

import org.jboss.logging.Logger一行是红色的,没有这个Logger类,依赖树一看果然没有jboss-logging这个包。

果然在这次升级的过程中jboss-logging的包被排除了,其实这个hibernate-valifator包的org.hibernate.validator.internal.util.logging下多个

类都出现错误,都是使用了jboss-logging中的依赖。

所以出现了以上错误。加上jboss-logging依赖,项目正常启动。

-------------------------------------------------------------------------------------------

至于springboot为什么引入hibernate-valifator,这个是干嘛用的? 去查一下Jsr-303,顺便可以看下springboot中属性绑定ConfigurationPropertiesBinder中的

getValidators方法就知道了。

posted @ 2021-10-18 21:23  她曾是他的梦  阅读(3812)  评论(0编辑  收藏  举报