Spring MVC返回SseEmitter时触发IncompatibleClassChangeError问题
解决Spring MVC/Spring Boot中SSE实现的IncompatibleClassChangeError错误
问题说明
尝试基于XML配置的Spring MVC实现Server-Sent Events(SSE),访问/subscribe-sse接口时触发IncompatibleClassChangeError;使用Spring Boot实现SSE时,也遇到完全相同的错误。
环境信息
- Java版本:sourceCompatibility = '1.8',targetCompatibility = '1.8'
- Servlet API: 4.0.1
- Spring依赖版本:
- spring-webmvc: 5.2.0
- spring-web: 5.3.8
控制器代码
@GetMapping(path = "/subscribe-sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public SseEmitter subscribe() { SseEmitter emitter = new SseEmitter(Long.MAX_VALUE); return emitter; }
错误栈信息
java.lang.IncompatibleClassChangeError: Expected non-static field org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.logger org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:128) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) javax.servlet.http.HttpServlet.service(HttpServlet.java:502) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) javax.servlet.http.HttpServlet.service(HttpServlet.java:596) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
解决方案
核心原因
错误根源是Spring的web相关依赖版本不一致:spring-webmvc和spring-web属于Spring框架的紧密耦合模块,版本必须完全匹配。不同版本的模块中,内部类的字段定义(比如ServletInvocableHandlerMethod.logger)可能发生变化(比如从非静态改为静态),导致类加载时出现兼容性冲突。
具体修复步骤
统一Spring web依赖版本
将spring-webmvc和spring-web调整为同一版本,比如都使用5.3.8或都使用5.2.0。以Gradle配置为例:dependencies { implementation 'org.springframework:spring-webmvc:5.3.8' implementation 'org.springframework:spring-web:5.3.8' // 其他依赖... }Spring Boot项目优化
如果是Spring Boot项目,无需手动指定spring-web和spring-webmvc的版本,直接引入spring-boot-starter-web依赖即可,Spring Boot的依赖管理会自动维护所有Spring组件的版本一致性:dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' // 其他依赖... }
验证
修改依赖版本后,重新构建项目并启动服务,访问/subscribe-sse接口即可正常处理SSE请求,不会再触发IncompatibleClassChangeError。
内容的提问来源于stack exchange,提问作者Nadim Mahmud
相关产品推荐
相关产品推荐

