Spring嵌入式Tomcat启动报错:Servlet.init()抛出NoSuchMethodException
Spring Web应用嵌入式Tomcat启动报错排查
我正在搭建第一个Spring Web应用,在main方法中配置了嵌入式Tomcat服务器,但启动时抛出CGLIB相关的NoSuchMethodException,推测是Spring配置问题但无法定位具体原因。项目完整代码已上传至代码仓库。
报错信息
INFO: 1 Spring WebApplicationInitializers detected on classpath sept. 29, 2023 11:46:04 AM org.apache.catalina.core.ApplicationContext log INFO: Initializing Spring DispatcherServlet 'dispatcher' sept. 29, 2023 11:46:05 AM org.apache.catalina.core.ApplicationContext log SEVERE: Servlet.init() for servlet [dispatcher] threw exception org.springframework.cglib.core.CodeGenerationException: java.lang.NoSuchMethodException-->com.gaetanl.resumebuilder.PersistenceConfig$$SpringCGLIB$$0.CGLIB$SET_THREAD_CALLBACKS([Lorg.springframework.cglib.proxy.Callback;) at org.springframework.cglib.proxy.Enhancer$EnhancerFactoryData.<init>(Enhancer.java:501) at org.springframework.cglib.proxy.Enhancer.wrapCachedClass(Enhancer.java:801) at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.lambda$new$1(AbstractClassGenerator.java:108) at org.springframework.cglib.core.internal.LoadingCache.lambda$createEntry$1(LoadingCache.java:52) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:57) at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:130) at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:317) at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:562) at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:407) at org.springframework.context.annotation.ConfigurationClassEnhancer.createClass(ConfigurationClassEnhancer.java:138) at org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:109) at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:531) at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:308) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:358) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:150) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:771) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:589) at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:706) at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:583) at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:537) at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:169) at jakarta.servlet.GenericServlet.init(GenericServlet.java:143) at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:121) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:944) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:808) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4601) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4894) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:846) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:241) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:433) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:918) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) at org.apache.catalina.startup.Tomcat.start(Tomcat.java:485) at com.gaetanl.resumebuilder.Application.run(Application.java:91) at com.gaetanl.resumebuilder.Application.main(Application.java:32) Caused by: java.lang.NoSuchMethodException: com.gaetanl.resumebuilder.PersistenceConfig$$SpringCGLIB$$0.CGLIB$SET_THREAD_CALLBACKS([Lorg.springframework.cglib.proxy.Callback;) at java.base/java.lang.Class.getDeclaredMethod(Class.java:2772) at org.springframework.cglib.proxy.Enhancer.getCallbacksSetter(Enhancer.java:901) at org.springframework.cglib.proxy.Enhancer$EnhancerFactoryData.<init>(Enhancer.java:490) ... 52 more sept. 29, 2023 11:46:05 AM org.apache.catalina.core.StandardContext loadOnStartup SEVERE: Servlet [dispatcher] in web application [/resume-builder-1.0-SNAPSHOT] threw load() exception java.lang.NoSuchMethodException: com.gaetanl.resumebuilder.PersistenceConfig$$SpringCGLIB$$0.CGLIB$SET_THREAD_CALLBACKS([Lorg.springframework.cglib.proxy.Callback;) at java.base/java.lang.Class.getDeclaredMethod(Class.java:2772) at org.springframework.cglib.proxy.Enhancer.getCallbacksSetter(Enhancer.java:901) at org.springframework.cglib.proxy.Enhancer$EnhancerFactoryData.<init>(Enhancer.java:490) at org.springframework.cglib.proxy.Enhancer.wrapCachedClass(Enhancer.java:801) at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.lambda$new$1(AbstractClassGenerator.java:108) at org.springframework.cglib.core.internal.LoadingCache.lambda$createEntry$1(LoadingCache.java:52) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:57) at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:130) at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:317) at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:562) at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:407) at org.springframework.context.annotation.ConfigurationClassEnhancer.createClass(ConfigurationClassEnhancer.java:138) at org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:109) at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:531) at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:308) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:358) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:150) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:771) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:589) at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:706) at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:583) at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:537) at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:169) at jakarta.servlet.GenericServlet.init(GenericServlet.java:143) at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:121) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:944) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:808) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4601) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4894) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:846) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:241) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:433) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:918) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) at org.apache.catalina.startup.Tomcat.start(Tomcat.java:485) at com.gaetanl.resumebuilder.Application.run(Application.java:91) at com.gaetanl.resumebuilder.Application.main(Application.java:32)
问题分析与解决方案
核心错误原因
报错指向PersistenceConfig类的CGLIB代理类缺少CGLIB$SET_THREAD_CALLBACKS方法,通常由以下情况导致:
- 版本兼容性问题:Spring版本与Java版本不匹配,CGLIB在Java 9+模块化环境下需要特定Spring版本支持(如Spring 5.3+适配Java 8-17,Spring 6+要求Java 17+)。
- 依赖冲突:项目中存在多版本的CGLIB或Spring核心依赖,导致类加载混乱,代理类生成失败。
- 配置类限制:
PersistenceConfig被声明为final类,或其中的方法被标记为final,导致CGLIB无法生成代理子类。
解决步骤
- 版本对齐:检查并确保Spring版本与当前Java版本兼容,调整pom.xml或build.gradle中的依赖版本。
- 清理依赖冲突:使用依赖分析工具(如
mvn dependency:tree或gradle dependencies)排查重复依赖,排除冲突的CGLIB/Spring包,统一依赖版本。 - 修改配置类:移除
PersistenceConfig类的final修饰符,确保配置方法也未被标记为final,允许CGLIB生成代理。 - 切换代理模式:若不想使用CGLIB,可在Spring配置中设置
proxyTargetClass=false,强制使用JDK动态代理(需配置类实现对应接口)。
内容的提问来源于stack exchange,提问作者Gaetan L.
相关产品推荐
相关产品推荐

