Quarkus 1.10.5整合Atmosphere报JSR356配置异常,寻求WebSocket开启方案
问题根因定位
你遇到的 ServerContainer is null 异常,本质是两套初始化机制的时序冲突导致的,和之前配置的 Servlet 异步支持没有直接关联:
- Quarkus 1.10.5.Final 版本的
quarkus-undertow-websockets扩展存在初始化时序差:该扩展会在所有 Servlet 上下文初始化流程走完之后,才完成 WebSocket 引擎的部署,把 ServerContainer 实例绑定到 ServletContext 属性上。而 Atmosphere 的JSR356AsyncSupport是跟着 Vaadin Servlet 的初始化流程触发加载的,这个阶段上下文里还没有写入对应的属性,自然取到 null。 - Quarkus 原生的 WebSocket 扩展默认不会把 ServerContainer 暴露到全局 ServletContext 域,只有当应用显式注册了
@ServerEndpoint标注的 JSR-356 端点时,才会做属性绑定,单靠引入依赖是不会自动完成绑定的。
这种 null 值会直接触发 Atmosphere 的自动降级逻辑,切到不支持 WebSocket 的Servlet30CometSupport实现,和你之前加的 Servlet 异步支持配置没有关联,自然无法解决问题。
分步解决操作
- 第一步:对齐依赖版本
确保引入的 websocket 依赖和 Quarkus 核心版本完全匹配,不要跨版本混用 Undertow 相关的扩展,避免内核API不兼容:<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-undertow-websockets</artifactId> <version>1.10.5.Final</version> </dependency> - 第二步:手动补全 ServletContext 的 ServerContainer 绑定
编写一个实现io.quarkus.undertow.ServletDeploymentListener的 CDI Bean,在 Undertow 完成部署的阶段,把容器已经初始化好的 ServerContainer 显式写入到 ServletContext 属性中,匹配 Atmosphere 取数的key:
这个操作直接绕开了扩展的初始化时序问题,不需要修改 Atmosphere 的源码逻辑。@Singleton public class WebSocketContextBinder implements ServletDeploymentListener { @Inject ServerContainer injectedContainer; @Override public void deploymentInitialized(ServletDeploymentContext deployContext) { ServletContext ctx = deployContext.servletContext(); // 严格按照 Atmosphere 读取的key写入属性 ctx.setAttribute(ServerContainer.class.getName(), injectedContainer); } } - 第三步:修正 Servlet 注册规则
删掉之前手动通过ServletBuildItem重复注册 QuarkusVaadinServlet 的代码,重复手动注册会打乱 Quarkus Vaadin 扩展自带的 Servlet 优先级逻辑,进一步加剧初始化时序的混乱。只需要在application.properties里配置异步支持即可,不需要硬编码 Servlet 构造逻辑:# 为 Vaadin Servlet 开启异步支持 quarkus.undertow.servlet."vaadin-servlet".async-supported=true - 第四步:关闭 Atmosphere 的自动降级逻辑
因为 Atmosphere 的降级判断是在属性为空时立刻触发,哪怕后续我们补全了上下文属性,也不会重新加载 JSR356 的实现。需要通过初始化参数强制 Atmosphere 固定使用 JSR356 作为底层实现:# 强制指定 Atmosphere 异步实现类 quarkus.vaadin.servlet.init-params.org.atmosphere.cpr.asyncSupport=org.atmosphere.container.JSR356AsyncSupport
避坑注意事项
- 不要在 Quarkus 1.10.5.Final 版本下升级 Atmosphere 到 2.4.30 以上的版本,高版本 Atmosphere 对新 Undertow 的适配逻辑和该老版本的 Servlet 容器实现不兼容,会触发类加载、端点映射的连锁异常。
- 不要尝试通过 web.xml 配置 JSR-356 的 WebSocket 端点,Quarkus 1.10 版本的 Undertow 适配层不支持解析 web.xml 中的 WebSocket 配置项,配置完全不生效。
- 完成上述配置后,不需要额外给 WebSocket 路径加 Undertow 的路由规则,Atmosphere 会自动接管自己的端点映射流程。
内容的提问来源于stack exchange,提问作者Martin Vysny
相关产品推荐
相关产品推荐

