Tomcat9部署WAR包报错:ASM ClassReader无法解析类文件(不支持新Java类文件版本)
Tomcat9部署WAR包报错:ASM ClassReader无法解析类文件(不支持新Java类文件版本)
我瞅你这情况是:自己打包的WAR包在本地Java项目跑、Tomcat8.5部署都没问题,一放到Tomcat9上就部署失败了。先把你贴的报错日志整理一下:
10-Feb-2025 15:19:14.866 SEVERE [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployWAR Error deploying web application archive [C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\test.war] java.lang.IllegalStateException: Error starting child at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:602) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:571) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:603) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1014) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1866) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) 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:123) at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:816) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:468) at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1633) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:308) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109) at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:973) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1172) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1176) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1154) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) at java.base/java.lang.Thread.run(Thread.java:1583) Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/test]] at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:406) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:179) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:599) ... 24 more Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'adminDaoImpl': Unsatisfied dependency expressed through field 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in com.baseltech.BaselTechBootApplication: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.hibernate.SessionFactory]: Factory method 'getSessionFactory' threw exception; nested exception is org.hibernate.MappingException: Failed to scan classpath for unlisted classes at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1420) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:173) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:153) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:95) at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:172) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4450) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) ... 25 more Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in com.baseltech.BaselTechBootApplication: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.hibernate.SessionFactory]: Factory method 'getSessionFactory' threw exception; nested exception is org.hibernate.MappingException: Failed to scan classpath for unlisted classes at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:635) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1176) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1307) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ... 48 more Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.hibernate.SessionFactory]: Factory method 'getSessionFactory' threw exception; nested exception is org.hibernate.MappingException: Failed to scan classpath for unlisted classes at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:650) ... 61 more Caused by: org.hibernate.MappingException: Failed to scan classpath for unlisted classes at org.springframework.orm.hibernate5.LocalSes
从日志里的org.hibernate.MappingException: Failed to scan classpath for unlisted classes能看出来,问题根源大概率是下面两个情况之一:
- Java编译版本太高:Tomcat9默认支持Java8到11(不同小版本略有区别),要是你项目用Java12及以上版本编译,Tomcat9里的ASM库(用来解析类文件的工具)不支持新的类文件版本,自然扫描失败。
- Hibernate和Tomcat的ASM依赖冲突:Tomcat9自带了ASM库,而你项目里Hibernate依赖的ASM版本和Tomcat的不一样,类加载的时候就会冲突,导致扫描类路径失败。
给你几个解决办法,按顺序试试:
办法一:调整项目的Java编译版本
先看看你项目的编译版本配置:
- 用Maven的话,打开
pom.xml找<maven.compiler.source>和<maven.compiler.target>,改成Tomcat9支持的版本(推荐Java8或11):
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target>
- 用Gradle的话,修改
build.gradle里的sourceCompatibility和targetCompatibility:
sourceCompatibility = 1.8 targetCompatibility = 1.8
改完重新打包WAR,再部署到Tomcat9上试试。
办法二:排除Hibernate里的ASM依赖,用Tomcat自带的
如果是依赖冲突的问题,以Maven为例,在Hibernate核心依赖里排除ASM的传递依赖:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>你的Hibernate版本</version> <exclusions> <exclusion> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> </exclusion> <exclusion> <groupId>org.ow2.asm</groupId> <artifactId>asm-commons</artifactId> </exclusion> <exclusion> <groupId>org.ow2.asm</groupId> <artifactId>asm-tree</artifactId> </exclusion> </exclusions> </dependency>
这样项目就会用Tomcat9自带的ASM库,避免版本冲突。
办法三:升级Tomcat9到最新小版本
要是你用的Tomcat9是比较老的版本,可能对高版本Java支持不够完善,去Tomcat官网下最新的Tomcat9.x版本,替换现有环境后再部署WAR包。
备注:内容来源于stack exchange,提问作者SWIK




