问题描述:
最近用idea的debug模式调试公司的项目时遇到了一个问题,项目在启动的时候抛出了异常:
Java.lang.NoClassDefFoundError: Could not initialize class org.springframework.beans.factory.BeanCreationException
起初以为是因为找不到相关依赖导致的问题,后来发现并没有那么简单,耗费了大量时间才终于解决了这个问题。
报错信息如下:
java.lang.NoClassDefFoundError: Could not initialize class org.springframework.beans.factory.BeanCreationException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[spring-beans-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) ~[spring-beans-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) ~[spring-beans-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) ~[spring-beans-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:237) ~[spring-context-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:703) ~[spring-context-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:527) ~[spring-context-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443) ~[spring-web-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325) ~[spring-web-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) ~[spring-web-4.3.30.RELEASE.jar:4.3.30.RELEASE]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4678) ~[catalina.jar:9.0.36]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5139) ~[catalina.jar:9.0.36]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.36]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717) ~[catalina.jar:9.0.36]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690) ~[catalina.jar:9.0.36]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705) ~[catalina.jar:9.0.36]
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1727) ~[catalina.jar:9.0.36]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_181]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_181]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_181]
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:288) ~[tomcat-coyote.jar:9.0.36]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) ~[?:1.8.0_181]
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) ~[?:1.8.0_181]
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:456) ~[catalina.jar:9.0.36]
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:405) ~[catalina.jar:9.0.36]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_181]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_181]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_181]
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:288) ~[tomcat-coyote.jar:9.0.36]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) ~[?:1.8.0_181]
原因分析:
1. 代码问题?
BeanCreationException一般是bean注入失败或者是找不到对应的bean,所以刚开始思路就放在检查代码上,一番检查后发现代码并无问题,然后对配置文件进行检查,也没有检查出问题。
2.依赖问题?jar缺失或jar冲突?
还有一个问题可能导致此异常,就是项目里的依赖不完整或者有冲突的jar包存在,在这种思路下我还真的发现了冲突的jar包,spring的核心包有两个版本,如下图:
于是我尝试删除其中一个版本的jar,可删除后发现项目代码直接报错,后来发现虽然有两个版本的jar但代码层面并不冲突,所以也不是这个问题
3.转变思路:会不会是因为运行模式导致的?
我尝试用idea的run模式(非debug模式)运行项目,神奇的事情发生了,项目竟然可以跑起来。我又尝试用debug模式运行,项目依然报错,于是我排除了1、2的问题,开始把问题锁定在项目的启动方式上。网上说debug模式不能运行可能是因为项目中打有断点没取消导致的,于是我将所有的断点都取消掉,再次运行还是不行。
4.更进一步:jvm性能问题?
在出现这个问题之前,我从未把问题深入到jvm上,因为jvm对我来说太过复杂。但这次我不得不直面它。
JVM有三大性能调优参数 -Xms,-Xmx,-Xss
-Xss:规定了每个线程虚拟机栈及堆栈的大小,一般情况下,256k是足够的,此配置将会影响此进程中并发线程数的大小。
-Xms:表示初始化JAVA堆的大小及该进程刚创建出来的时候,他的专属JAVA堆的大小,一旦对象容量超过了JAVA堆的初始容量,JAVA堆将会自动扩容到-Xmx大小。
-Xmx:表示java堆可以扩展到的最大值,在很多情况下,通常将-Xms和-Xmx设置成一样的,因为当堆不够用而发生扩容时,会发生内存抖动影响程序运行时的稳定性。
解决方案:
如果是使用tomcat启动项目的话,可以在“虚拟机选项”添加-Xss参数配置,大小可根据实际情况进行设置,我这里设置2m才可以正常运行