{"record":{"id":"cb2a01cc8bf9d417","repo":"apache/shenyu","slug":"extension-clazz-clazz-is-not-interface","errorCode":null,"errorMessage":"extension clazz (clazz) is not interface!","messagePattern":"extension clazz \\(clazz\\) is not interface!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"shenyu-spi/src/main/java/org/apache/shenyu/spi/ExtensionLoader.java","lineNumber":97,"sourceCode":"        if (!Objects.equals(clazz, ExtensionFactory.class)) {\n            ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getExtensionClassesEntity();\n        }\n    }\n    \n    /**\n     * Gets extension loader.\n     *\n     * @param <T>   the type parameter\n     * @param clazz the clazz\n     * @param cl    the cl\n     * @return the extension loader.\n     */\n    public static <T> ExtensionLoader<T> getExtensionLoader(final Class<T> clazz, final ClassLoader cl) {\n        \n        Objects.requireNonNull(clazz, \"extension clazz is null\");\n        \n        if (!clazz.isInterface()) {\n            throw new IllegalArgumentException(\"extension clazz (\" + clazz + \") is not interface!\");\n        }\n        if (!clazz.isAnnotationPresent(SPI.class)) {\n            throw new IllegalArgumentException(\"extension clazz (\" + clazz + \") without @\" + SPI.class + \" Annotation\");\n        }\n        ExtensionLoader<T> extensionLoader = (ExtensionLoader<T>) LOADERS.get(clazz);\n        if (Objects.nonNull(extensionLoader)) {\n            return extensionLoader;\n        }\n        LOADERS.putIfAbsent(clazz, new ExtensionLoader<>(clazz, cl));\n        return (ExtensionLoader<T>) LOADERS.get(clazz);\n    }\n    \n    /**\n     * Gets extension loader.\n     *\n     * @param <T>   the type parameter\n     * @param clazz the clazz\n     * @return the extension loader","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-spi/src/main/java/org/apache/shenyu/spi/ExtensionLoader.java#L79-L115","documentation":"ShenYu's SPI mechanism (ExtensionLoader.getExtensionLoader) only works with interfaces annotated with @SPI. This IllegalArgumentException is thrown when the Class passed to getExtensionLoader is a concrete class, enum, or other non-interface type. The SPI framework loads implementations via META-INF/shenyu/ resource files keyed by the interface, so only interfaces are valid extension types.","triggerScenarios":"Calling ExtensionLoader.getExtensionLoader(SomeConcreteClass.class) where the argument is a class or abstract class rather than an interface.","commonSituations":"Developer mistakenly passes the implementation class instead of the SPI interface (e.g. getExtensionLoader(LoadBalanceMockImpl.class) instead of getExtensionLoader(LoadBalance.class)); refactoring turned a former interface into a class; copy-paste of the wrong Class literal.","solutions":["Pass the SPI interface type instead of an implementation class","Verify the type is an interface: clazz.isInterface() must be true","Annotate the interface with @org.apache.shenyu.spi.SPI"],"exampleFix":"// before\nExtensionLoader<LoadBalanceMockImpl> loader = ExtensionLoader.getExtensionLoader(LoadBalanceMockImpl.class);\n// after\nExtensionLoader<LoadBalance> loader = ExtensionLoader.getExtensionLoader(LoadBalance.class);","handlingStrategy":"validation","validationCode":"if (!LoadBalance.class.isInterface()) { throw new IllegalArgumentException(\"must pass an SPI interface\"); }\nExtensionLoader<LoadBalance> loader = ExtensionLoader.getExtensionLoader(LoadBalance.class);","typeGuard":"static <T> boolean isSpiInterface(Class<T> c) { return c.isInterface(); }","tryCatchPattern":"try { loader = ExtensionLoader.getExtensionLoader(clazz); } catch (IllegalArgumentException e) { log.error(\"Bad SPI type: {}\", e.getMessage()); throw e; }","preventionTips":["Always pass the interface type, never an implementation class","Mark SPI interfaces with @SPI so intent is visible","Wrap SPI bootstrap in a startup check/fail-fast init"],"tags":["spi","java","illegal-argument"],"backgroundTag":"invalid-argument-value","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}