apache / apache/shenyu

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

Open
#6,791 1 comment 0 reactions 0 assignees View on GitHub
client: register priority: medium type: bug
Dominant language
Java
Stars
8.8k
Forks
3.1k
Avg merge
7d 1h
Merged PRs (30d)
85

Description

- 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.registerEndpoint` → `serverContainer.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`](docs/scan2-2026-08-02/06-medium-tiers.md)._

Contributor guide

No contributing guide indexed for this repository

Research direction

Read AbstractContextRefreshedEventListener.java around markRegistered and SpringWebSocketClientEventListener.java around getBeans and registerEndpointsBeans. Trace the call into ShenyuServerEndpointerExporter.java:112, then reproduce or inspect a second ContextRefreshedEvent. Done means repeated refreshes no longer invoke duplicate endpoint registration or fail with a DeploymentException/IllegalStateException.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.