解决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 <kevin.pollet@serli.com> (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方法就知道了。