部署生产环境时出现ObjectStreamClass$Caches类转换异常求助
生产环境Tomcat类转换异常排查解决
生产环境部署时出现以下错误,测试环境无此异常:
org.apache.juli.logging.DirectJDKLog 175 log - Failed to clear soft references from ObjectStreamClass$Caches for web application [ROOT] java.lang.ClassCastException: class java.io.ObjectStreamClass$Caches$1 cannot be cast to class java.util.Map (java.io.ObjectStreamClass$Caches$1 and java.util.Map are in module java.base of loader 'bootstrap')
完整堆栈信息:
org.apache.juli.logging.DirectJDKLog 175 log - Failed to clear soft references from ObjectStreamClass$Caches for web application [ROOT] java.lang.ClassCastException: class java.io.ObjectStreamClass$Caches$1 cannot be cast to class java.util.Map (java.io.ObjectStreamClass$Caches$1 and java.util.Map are in module java.base of loader 'bootstrap') at org.apache.catalina.loader.WebappClassLoaderBase.clearCache(WebappClassLoaderBase.java:2207) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesObjectStreamClassCaches(WebappClassLoaderBase.java:2194) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.loader.WebappClassLoaderBase.clearReferences(WebappClassLoaderBase.java:1567) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.loader.WebappClassLoaderBase.stop(WebappClassLoaderBase.java:1497) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.loader.WebappLoader.stopInternal(WebappLoader.java:442) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5367) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1445) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1434) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?] at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) [?:?] at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:1001) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1445) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1434) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?] at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) [?:?] at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:1001) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.core.StandardService.stopInternal(StandardService.java:474) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.core.StandardServer.stopInternal(StandardServer.java:791) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.apache.catalina.startup.Tomcat.stop(Tomcat.java:380) [tomcat-embed-core-9.0.12.jar!/:9.0.12] at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.stopTomcat(TomcatWebServer.java:250) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE] at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.stop(TomcatWebServer.java:306) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.stopAndReleaseWebServer(ServletWebServerApplicationContext.java:309) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.0.RELEASE.jar!/:2.1.0.RELEASE] at me.zhengjie.AppRun.main(AppRun.java:38) [classes!/:1.5] at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?] at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?] at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [eladmin-system.jar.202404160913:1.5] at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [eladmin-system.jar.202404160913:1.5] at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [eladmin-system.jar.202404160913:1.5] at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [eladmin-system.jar.202404160913:1.5]
问题原因
- JDK与Tomcat版本不兼容:Tomcat 9.0.12清理
ObjectStreamClass缓存时,会通过反射将JDK内部的ObjectStreamClass$Caches$1强转为Map,但JDK 9及以上版本中该内部类实现已变更,不再直接实现Map接口,导致强转失败。测试环境大概率使用JDK 8,因此未触发该问题。 - Spring Boot版本过旧:Spring Boot 2.1.0.RELEASE内嵌的Tomcat 9.0.12对JDK 9+的兼容性处理不完善,未修复该反射强转问题。
解决办法
- 升级依赖版本:
- 直接升级Spring Boot到2.1.13.RELEASE及以上版本,该版本内嵌的Tomcat 9.0.40+已修复此兼容问题。
- 若不想升级Spring Boot,可单独指定Tomcat依赖版本为9.0.40或更高:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <version>9.0.80</version> <!-- 或其他兼容的高版本 --> </dependency>
- 统一JDK版本:将生产环境JDK版本降级为JDK 8,与测试环境保持一致,避免版本差异引发兼容问题。
- 临时规避方案(不推荐):设置系统属性
org.apache.catalina.loader.WebappClassLoaderBase.ENABLE_CLEAR_REFERENCES=false,关闭Tomcat缓存清理逻辑,但可能导致内存泄漏风险,仅作为临时过渡方案。
内容的提问来源于stack exchange,提问作者我就是骚浪贱
相关产品推荐
相关产品推荐

