Skip to content

[BUG] WebSocket endpoint re-registered before markRegistered guard — duplicate endpoint registration crashes context refresh #6791

Description

@Aias00
  • Severity: Medium
  • Location:
    shenyu-client/shenyu-client-websocket/shenyu-client-spring-websocket/src/main/java/org/apache/shenyu/client/spring/websocket/init/SpringWebSocketClientEventListener.java:113-115 (registerEndpointsBeans call in getBeans); guard at shenyu-client-core/.../AbstractContextRefreshedEventListener.java:149 (markRegistered)

Description:
The parent onApplicationEvent calls getBeans(context) (line 145) before markRegistered() (line 149). The WebSocket override of getBeans performs the side-effecting registerEndpointsBeans(context, endpointBeans) (line 114), which calls ShenyuServerEndpointerExporter.registerEndpointserverContainer.addEndpoint(endpointConfig) for every @ShenyuServerEndpoint bean. The once-only markRegistered guard protects handle and URI publishing, but does not protect this getBeans side effect. On a second ContextRefreshedEvent (Spring MVC parent+child contexts, or integration tests refreshing multiple contexts), addEndpoint is invoked again for the same path; per the Jakarta WebSocket spec and Tomcat's WsServerContainer, re-adding a duplicate path throws DeploymentException (wrapped as IllegalStateException at ShenyuServerEndpointerExporter.java:112), failing the context refresh.

Impact:
Duplicate websocket endpoint registration crashes context refresh in hierarchical/multi-refresh contexts.

Suggested fix:
Move registerEndpointsBeans out of getBeans into handle (which is post-guard), or track endpoint registration with its own AtomicBoolean.

Confidence: Medium


Identified during the 2026-08-02 deep re-scan; full list in docs/scan2-2026-08-02/06-medium-tiers.md.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions