{"record":{"id":"5f017dd38d8ef281","repo":"apache/dubbo","slug":"the-method-s-of-interface-s-is-not-adaptive-meth","errorCode":null,"errorMessage":"The method %s of interface %s is not adaptive method!","messagePattern":"The method (.+?) of interface (.+?) is not adaptive method!","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java","lineNumber":58,"sourceCode":"\n    private static final Logger logger = LoggerFactory.getLogger(AdaptiveClassCodeGenerator.class);\n\n    private static final String CLASS_NAME_INVOCATION = \"org.apache.dubbo.rpc.Invocation\";\n\n    private static final String CODE_PACKAGE = \"package %s;\\n\";\n\n    private static final String CODE_IMPORTS = \"import %s;\\n\";\n\n    private static final String CODE_CLASS_DECLARATION = \"public class %s$Adaptive implements %s {\\n\";\n\n    private static final String CODE_METHOD_DECLARATION = \"public %s %s(%s) %s {\\n%s}\\n\";\n\n    private static final String CODE_METHOD_ARGUMENT = \"%s arg%d\";\n\n    private static final String CODE_METHOD_THROWS = \"throws %s\";\n\n    private static final String CODE_UNSUPPORTED =\n            \"throw new UnsupportedOperationException(\\\"The method %s of interface %s is not adaptive method!\\\");\\n\";\n\n    private static final String CODE_URL_NULL_CHECK =\n            \"if (arg%d == null) throw new IllegalArgumentException(\\\"url == null\\\");\\n%s url = arg%d;\\n\";\n\n    private static final String CODE_EXT_NAME_ASSIGNMENT = \"String extName = %s;\\n\";\n\n    private static final String CODE_EXT_NAME_NULL_CHECK = \"if(extName == null) \"\n            + \"throw new IllegalStateException(\\\"Failed to get extension (%s) name from url (\\\" + url.toString() + \\\") use keys(%s)\\\");\\n\";\n\n    private static final String CODE_INVOCATION_ARGUMENT_NULL_CHECK =\n            \"if (arg%d == null) throw new IllegalArgumentException(\\\"invocation == null\\\"); \"\n                    + \"String methodName = arg%d.getMethodName();\\n\";\n\n    private static final String CODE_SCOPE_MODEL_ASSIGNMENT =\n            \"ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), %s.class);\\n\";\n    private static final String CODE_EXTENSION_ASSIGNMENT =\n            \"%s extension = (%<s)scopeModel.getExtensionLoader(%s.class).getExtension(extName);\\n\";\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java#L40-L76","documentation":"This is a generated-code template (CODE_UNSUPPORTED) emitted by AdaptiveClassCodeGenerator for methods on an SPI interface that are NOT annotated with @Adaptive. At runtime, the generated $Adaptive class throws UnsupportedOperationException when such a method is invoked. It signals that the called method is not adaptive and therefore the adaptive instance cannot route it to a concrete extension.","triggerScenarios":"At runtime, calling a non-@Adaptive method on an adaptive extension instance obtained via ExtensionLoader.getAdaptiveExtension(). The generated code unconditionally throws for any method lacking the @Adaptive annotation.","commonSituations":"Calling an SPI interface method that was not marked @Adaptive on the adaptive proxy. For example, Protocol has some methods annotated @Adaptive and some not; calling a non-adaptive method through the adaptive instance. Happens when framework code or user code obtains the wrong type of extension instance.","solutions":["Check which method is being called and whether it is annotated @Adaptive on the SPI interface.","Obtain the concrete extension instance by name instead of the adaptive instance: extensionLoader.getExtension(name) rather than getAdaptiveExtension().","If you are the SPI author and the method should be adaptive, annotate it with @Adaptive."],"exampleFix":"// before\nProtocol adaptive = extensionLoader.getAdaptiveExtension();\nadaptive.someNonAdaptiveMethod(url); // throws\n\n// after\nProtocol concrete = extensionLoader.getExtension(\"dubbo\");\nconcrete.someNonAdaptiveMethod(url);","handlingStrategy":"validation","validationCode":"boolean isAdaptive = Arrays.stream(type.getMethods())\n    .anyMatch(m -> m.isAnnotationPresent(Adaptive.class));\nif (!isAdaptive) {\n    // cannot use adaptive instance for this method\n}","typeGuard":"static boolean isAdaptiveMethod(Class<?> spiType, String methodName, Class<?>... paramTypes) {\n    try {\n        Method m = spiType.getMethod(methodName, paramTypes);\n        return m.isAnnotationPresent(Adaptive.class);\n    } catch (NoSuchMethodException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    adaptiveExt.someMethod(url);\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"not adaptive method\")) {\n        // obtain a named extension instead\n        ext = loader.getExtension(\"default\");\n    } else throw e;\n}","preventionTips":["Check that the called method is @Adaptive before using the adaptive instance.","Use getExtension(name) for non-adaptive methods.","Familiarize yourself with which SPI methods are @Adaptive in Dubbo's core interfaces."],"tags":["spi","adaptive-extension","code-generation","runtime"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}