[BUG] Removed ext-lib plugin never unregistered from the plugin chain
- Dominant language
- Java
- Stars
- 8.8k
- Forks
- 3.1k
- Avg merge
- 7d 1h
- Merged PRs (30d)
- 85
Description
- Severity: High
- Location:
`shenyu-web/src/main/java/org/apache/shenyu/web/handler/ShenyuWebHandler.java:150-191` (`putExtPlugins` — only add/update, no removal); `shenyu-web/src/main/java/org/apache/shenyu/web/loader/ShenyuExtPathPluginJarLoader.java:62-65` (calls `removePluginClassLoader` only); `shenyu-web/src/main/java/org/apache/shenyu/web/loader/ShenyuLoaderService.java:104-112`
-
Description:
When an ext-lib jar is deleted from disk, `ShenyuExtPathPluginJarLoader.loadExtendPlugins` calls `ShenyuPluginClassLoaderHolder.removePluginClassLoader(removePath)`, which closes the classloader and `destroySingleton`s its Spring beans. However, `ShenyuLoaderService.loaderPlugins` only calls `webHandler.putExtPlugins(newPlugins)` — and `putExtPlugins` has add and update branches but **no removal branch**. Plugin removal from the live `plugins`/`sourcePlugins` lists is only reachable via `PluginHandlerEvent` (DELETE → `onPluginRemoved`), which the ext-lib scan never publishes.
-
Impact:
The stale `ShenyuPlugin` instance from the destroyed classloader stays in `ShenyuWebHandler.plugins`. The next request dispatching to that plugin hits beans whose singletons were just `destroySingleton`'d and a classloader that was `close()`'d → `BeanCreationException`/`NoClassDefFoundError`/NPE for the whole route.
-
Suggested fix:
Have `loadExtendPlugins` return the removed plugin names; have `ShenyuLoaderService` call a new `webHandler.removeExtPlugins(names)` that filters `plugins`/`sourcePlugins` by `named()` (copy-on-write).
-
Confidence: High
- Related existing: WEB-08 covers a race in `sourcePlugins` construction, not the missing removal path.
---
_Identified during the 2026-08-02 deep re-scan; full list in [`docs/scan2-2026-08-02/00-consolidated-critical-high.md`](docs/scan2-2026-08-02/00-consolidated-critical-high.md)._
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with ShenyuWebHandler.java:150-191, ShenyuExtPathPluginJarLoader.java:62-65, and ShenyuLoaderService.java:104-112 to trace deletion through loadExtendPlugins and loaderPlugins. Verify that deleting an ext-lib jar removes its named plugin from both plugins and sourcePlugins after the classloader is removed, preventing later dispatch to destroyed beans.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 56/100