alibaba / Sentinel

A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)
https://sentinelguard.io/
Apache License 2.0
22.41k stars 8.03k forks source link

[BUG] 1.8.1 SpiLoader 加载重复的JDK-SPI配置会报错 SpiLoaderException #3185

Open noseew opened 1 year ago

noseew commented 1 year ago

Issue Description

我看到新版本(1.8.1之后)SpiLoader 重写了JDK默认的SPI加载逻辑, 当遇到相同的SPI实现配置的时候,会报错SpiLoaderException,

Type: bug report

Describe what happened

具体代码如下

public final class SpiLoader<S> {
// ...
    public void load() {
    // ...
        // 这段代码会导致当项目中存在重复的SPI文件(接口=实现)时会报错, 而这不是JDK-SPI的默认行为
        if (classMap.containsKey(aliasName)) {
            Class<? extends S> existClass = classMap.get(aliasName);
            fail("Found repeat alias name for " + clazz.getName() + " and "
                    + existClass.getName() + ",SPI configuration file=" + fullFileName);
        }
    // ....
    }
 ...
}

Describe what you expected to happen

报错信息如下: com.alibaba.csp.sentinel.spi.SpiLoaderException: [com.alibaba.csp.sentinel.slotchain.ProcessorSlot]Found repeat alias name for com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowSlot and com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowSlot,SPI configuration file=META-INF/services/com.alibaba.csp.sentinel.slotchain.ProcessorSlot

我看到重复检测主要是针对@Spi注解的, 不过这也覆盖了JDK SPI的能力, 是否可以针对他们区别对待 Spi spi = clazz.getAnnotation(Spi.class);

How to reproduce it (as minimally and precisely as possible)

我们的项目中会存在多个sentinel的包, 甚至是多个不同版本的包, 而且可能会运行时动态加载一些额外的包, 所以会出现项目中出现相同SPI配置文件

sczyh30 commented 1 year ago

cc @cdfive