daguimu opened a new pull request, #16169:
URL: https://github.com/apache/dubbo/pull/16169
## Problem
`BitList.emptyList()` returns a shared static singleton instance. Since
`BitList` is mutable (supports `add()`, `addToTailList()`, `and()`, etc.), any
caller that modifies the returned "empty" list inadvertently mutates the
singleton, contaminating all subsequent callers.
In `AbstractDirectory`, the `invokers` field is initialized with
`BitList.emptyList()`. When the first interface's invokers are added, they
pollute the shared singleton. When a second interface later calls
`BitList.emptyList()`, it receives a list already containing the first
interface's invokers, causing traffic to be routed to the wrong instances and
resulting in `NoSuchMethodError`.
## Root Cause
```java
// Shared mutable singleton - any mutation affects all callers
private static final BitList emptyList = new
BitList(Collections.emptyList());
public static <T> BitList<T> emptyList() {
return emptyList; // returns the SAME instance every time
}
```
## Fix
Return a new `BitList` instance on each call to `emptyList()`, consistent
with how mutable collections should behave:
```java
public static <T> BitList<T> emptyList() {
return new BitList<>(Collections.emptyList());
}
```
## Tests Added
- `testEmptyListReturnsIndependentInstances` — Verifies each call returns a
distinct object
- `testEmptyListMutationDoesNotAffectOtherEmptyList` — Reproduces the exact
bug: adding elements to one empty list must not affect another (the core
scenario from #16131)
- `testEmptyListTailListMutationDoesNotAffectOtherEmptyList` — Verifies tail
list mutations are also isolated
- `testEmptyListIsInitiallyEmpty` — Confirms the returned list starts truly
empty
All 26 tests in `BitListTest` pass.
## Impact
- Minimal change: removes 1 static field, modifies 1 method (3 lines changed
in production code)
- No behavioral change for callers — they get the same empty `BitList`, just
a fresh instance
- No reference equality (`==`) checks exist against `BitList.emptyList()` in
the codebase
- Fixes a critical production bug where cross-interface invoker leakage
causes `NoSuchMethodError`
Fixes #16131
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]