{"record":{"id":"7e46c8b9837b31ea","repo":"alibaba/canal","slug":"extension-type-is-not-interface","errorCode":null,"errorMessage":"Extension type({}) is not interface!","messagePattern":"Extension type\\((.+?)\\) is not interface!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"client-adapter/common/src/main/java/com/alibaba/otter/canal/client/adapter/support/ExtensionLoader.java","lineNumber":76,"sourceCode":"    private final ConcurrentMap<String, Holder<Object>>              cachedInstances            = new ConcurrentHashMap<>();\n\n    private String                                                   cachedDefaultName;\n\n    private ConcurrentHashMap<String, IllegalStateException>         exceptions                 = new ConcurrentHashMap<>();\n\n    private static <T> boolean withExtensionAnnotation(Class<T> type) {\n        return type.isAnnotationPresent(SPI.class);\n    }\n\n    public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {\n        return getExtensionLoader(type, DEFAULT_CLASSLOADER_POLICY);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type, String classLoaderPolicy) {\n        if (type == null) throw new IllegalArgumentException(\"Extension type == null\");\n        if (!type.isInterface()) {\n            throw new IllegalArgumentException(\"Extension type(\" + type + \") is not interface!\");\n        }\n        if (!withExtensionAnnotation(type)) {\n            throw new IllegalArgumentException(\"Extension type(\" + type + \") is not extension, because WITHOUT @\"\n                                               + SPI.class.getSimpleName() + \" Annotation!\");\n        }\n\n        ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);\n        if (loader == null) {\n            EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type, classLoaderPolicy));\n            loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);\n        }\n        return loader;\n    }\n\n    private ExtensionLoader(Class<?> type, String classLoaderPolicy){\n        this.type = type;\n        this.classLoaderPolicy = classLoaderPolicy;\n    }","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/client-adapter/common/src/main/java/com/alibaba/otter/canal/client/adapter/support/ExtensionLoader.java#L58-L94","documentation":"Error \"Extension type({}) is not interface!\" thrown in alibaba/canal.","triggerScenarios":"Thrown at client-adapter/common/src/main/java/com/alibaba/otter/canal/client/adapter/support/ExtensionLoader.java:76 when the library encounters an invalid state.","commonSituations":"SPI type is not an interface. Enforce the interface contract at load time; concrete classes cannot be extension points.","solutions":["Only interface types can be used as extension points; change the type argument to an interface.","Refactor the extension point into an interface if it is currently a concrete/abstract class."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}