{"record":{"id":"1e669946f9bb0b4a","repo":"apache/dubbo","slug":"no-adaptive-method-exist-on-extension-type-getna","errorCode":null,"errorMessage":"No adaptive method exist on extension ${type.getName()}, refuse to create the adaptive class!","messagePattern":"No adaptive method exist on extension (.+?), refuse to create the adaptive class!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java","lineNumber":109,"sourceCode":"    private boolean hasAdaptiveMethod() {\n        return Arrays.stream(type.getMethods()).anyMatch(m -> m.isAnnotationPresent(Adaptive.class));\n    }\n\n    /**\n     * generate and return class code\n     */\n    public String generate() {\n        return this.generate(false);\n    }\n\n    /**\n     * generate and return class code\n     * @param sort - whether sort methods\n     */\n    public String generate(boolean sort) {\n        // no need to generate adaptive class since there's no adaptive method found.\n        if (!hasAdaptiveMethod()) {\n            throw new IllegalStateException(\"No adaptive method exist on extension \" + type.getName()\n                    + \", refuse to create the adaptive class!\");\n        }\n\n        StringBuilder code = new StringBuilder();\n        code.append(generatePackageInfo());\n        code.append(generateImports());\n        code.append(generateClassDeclaration());\n\n        Method[] methods = type.getMethods();\n        if (sort) {\n            Arrays.sort(methods, Comparator.comparing(Method::toString));\n        }\n        for (Method method : methods) {\n            code.append(generateMethod(method));\n        }\n        code.append('}');\n\n        if (logger.isDebugEnabled()) {","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java#L91-L127","documentation":"Thrown by AdaptiveClassCodeGenerator.generate() at class-generation time (not runtime) when the SPI interface has zero methods annotated with @Adaptive. The generator refuses to produce an adaptive class because there would be nothing to delegate adaptively. This is a configuration/design error in the SPI interface itself.","triggerScenarios":"ExtensionLoader.getAdaptiveExtension() is called for an interface that has no @Adaptive methods. Internally, generate() calls hasAdaptiveMethod() which checks all public methods for the annotation; if none is found, it throws. This happens during Dubbo startup or first access of the adaptive extension.","commonSituations":"A custom SPI interface was declared but none of its methods carry @Adaptive. Or an existing SPI's @Adaptive annotation was accidentally removed during a refactor. Dubbo's own core SPIs always have at least one adaptive method; this error almost always points to a user-defined SPI.","solutions":["Add @Adaptive to at least one method on the SPI interface that should be routed adaptively based on URL parameters.","If no adaptive behavior is needed, do not call getAdaptiveExtension() — use getExtension(name) to obtain a specific implementation instead.","Verify the @Adaptive import is org.apache.dubbo.common.extension.Adaptive and not a different annotation with the same simple name."],"exampleFix":"// before\npublic interface MySpi {\n    String doWork(URL url);\n}\n\n// after\npublic interface MySpi {\n    @Adaptive\n    String doWork(URL url);\n}","handlingStrategy":"validation","validationCode":"boolean hasAdaptive = Arrays.stream(spiInterface.getMethods())\n    .anyMatch(m -> m.isAnnotationPresent(Adaptive.class));\nif (!hasAdaptive) {\n    // do not call getAdaptiveExtension — design fix needed\n}","typeGuard":"static boolean hasAdaptiveMethod(Class<?> spiType) {\n    return spiType != null && Arrays.stream(spiType.getMethods())\n        .anyMatch(m -> m.isAnnotationPresent(Adaptive.class));\n}","tryCatchPattern":"try {\n    return loader.getAdaptiveExtension();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"No adaptive method\")) {\n        return loader.getDefaultExtension(); // or getExtension(name)\n    } else throw e;\n}","preventionTips":["Ensure at least one method on the SPI interface is annotated @Adaptive.","Do not call getAdaptiveExtension() on SPIs designed without adaptive methods.","Use getExtension(name) for deterministic extension selection."],"tags":["spi","adaptive-extension","code-generation","startup"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}