apache/dubbo · error · UnsupportedOperationException
The method %s of interface %s is not adaptive method!
Error message
The method %s of interface %s is not adaptive method!
What it means
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.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java:58
private static final Logger logger = LoggerFactory.getLogger(AdaptiveClassCodeGenerator.class);
private static final String CLASS_NAME_INVOCATION = "org.apache.dubbo.rpc.Invocation";
private static final String CODE_PACKAGE = "package %s;\n";
private static final String CODE_IMPORTS = "import %s;\n";
private static final String CODE_CLASS_DECLARATION = "public class %s$Adaptive implements %s {\n";
private static final String CODE_METHOD_DECLARATION = "public %s %s(%s) %s {\n%s}\n";
private static final String CODE_METHOD_ARGUMENT = "%s arg%d";
private static final String CODE_METHOD_THROWS = "throws %s";
private static final String CODE_UNSUPPORTED =
"throw new UnsupportedOperationException(\"The method %s of interface %s is not adaptive method!\");\n";
private static final String CODE_URL_NULL_CHECK =
"if (arg%d == null) throw new IllegalArgumentException(\"url == null\");\n%s url = arg%d;\n";
private static final String CODE_EXT_NAME_ASSIGNMENT = "String extName = %s;\n";
private static final String CODE_EXT_NAME_NULL_CHECK = "if(extName == null) "
+ "throw new IllegalStateException(\"Failed to get extension (%s) name from url (\" + url.toString() + \") use keys(%s)\");\n";
private static final String CODE_INVOCATION_ARGUMENT_NULL_CHECK =
"if (arg%d == null) throw new IllegalArgumentException(\"invocation == null\"); "
+ "String methodName = arg%d.getMethodName();\n";
private static final String CODE_SCOPE_MODEL_ASSIGNMENT =
"ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), %s.class);\n";
private static final String CODE_EXTENSION_ASSIGNMENT =
"%s extension = (%<s)scopeModel.getExtensionLoader(%s.class).getExtension(extName);\n";
View on GitHub (pinned to 3a3043227f)
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.
Example fix
// before
Protocol adaptive = extensionLoader.getAdaptiveExtension();
adaptive.someNonAdaptiveMethod(url); // throws
// after
Protocol concrete = extensionLoader.getExtension("dubbo");
concrete.someNonAdaptiveMethod(url); Defensive patterns
Strategy: validation
Validate before calling
boolean isAdaptive = Arrays.stream(type.getMethods())
.anyMatch(m -> m.isAnnotationPresent(Adaptive.class));
if (!isAdaptive) {
// cannot use adaptive instance for this method
} Type guard
static boolean isAdaptiveMethod(Class<?> spiType, String methodName, Class<?>... paramTypes) {
try {
Method m = spiType.getMethod(methodName, paramTypes);
return m.isAnnotationPresent(Adaptive.class);
} catch (NoSuchMethodException e) {
return false;
}
} Try / catch
try {
adaptiveExt.someMethod(url);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("not adaptive method")) {
// obtain a named extension instead
ext = loader.getExtension("default");
} else throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- url == null
- Failed to get extension (%s) name from url (${url}) use keys
- invocation == null
- No adaptive method exist on extension ${type.getName()}, ref
- Failed to create adaptive class for interface ${type.getName
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/5f017dd38d8ef281.
Report an issue: GitHub.