spring-projects/spring-framework · error · UnsupportedOperationException
Unexpected MethodOverride subclass: {}
Error message
Unexpected MethodOverride subclass: {} What it means
BeanDefinitionPropertiesCodeGenerator emits AOT code for method overrides but only knows how to handle LookupOverride and ReplaceOverride. Any other MethodOverride subclass hits an UnsupportedOperationException, since the generator has no code-emission strategy for it.
Source
Thrown at spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionPropertiesCodeGenerator.java:303
arguments.add(CodeBlock.of("$S", lookupOverride.getMethodName()));
arguments.add(CodeBlock.of("$S", lookupOverride.getBeanName()));
code.addStatement("$L.getMethodOverrides().addOverride(new $T($L))", BEAN_DEFINITION_VARIABLE,
LookupOverride.class, CodeBlock.join(arguments, ", "));
}
else if (methodOverride instanceof ReplaceOverride replaceOverride) {
Collection<CodeBlock> arguments = new ArrayList<>();
arguments.add(CodeBlock.of("$S", replaceOverride.getMethodName()));
arguments.add(CodeBlock.of("$S", replaceOverride.getMethodReplacerBeanName()));
List<String> typeIdentifiers = replaceOverride.getTypeIdentifiers();
if (!typeIdentifiers.isEmpty()) {
arguments.add(CodeBlock.of("java.util.List.of($S)",
StringUtils.collectionToDelimitedString(typeIdentifiers, ", ")));
}
code.addStatement("$L.getMethodOverrides().addOverride(new $T($L))", BEAN_DEFINITION_VARIABLE,
ReplaceOverride.class, CodeBlock.join(arguments, ", "));
}
else {
throw new UnsupportedOperationException("Unexpected MethodOverride subclass: " +
methodOverride.getClass().getName());
}
}
}
}
private CodeBlock generateValue(@Nullable String name, @Nullable Object value) {
PropertyNamesStack.push(name);
try {
return this.valueCodeGenerator.generateCode(value);
}
finally {
PropertyNamesStack.pop();
}
}
private Class<?> getInfrastructureType(RootBeanDefinition beanDefinition) {
if (beanDefinition.hasBeanClass()) {View on GitHub (pinned to e8729d0438)
Solutions
- Replace the custom MethodOverride subclass with LookupOverride or ReplaceOverride if the semantics allow.
- If you maintain the custom override, contribute a dedicated AOT code generator/hook for it upstream or avoid AOT for that bean.
- Fall back to JIT (non-AOT) runtime if the custom override is mandatory.
Example fix
// before
beanDef.getMethodOverrides().addOverride(new MyCustomOverride("foo"));
// after
beanDef.getMethodOverrides().addOverride(new LookupOverride("foo", "replacementBean")); Defensive patterns
Strategy: type-guard
Validate before calling
for (MethodOverride o : beanDefinition.getMethodOverrides()) {
if (!(o instanceof LookupOverride || o instanceof ReplaceOverride)) {
throw new IllegalStateException("Unsupported override type for AOT: " + o.getClass());
}
} Type guard
boolean aotSupportedOverride(MethodOverride o) {
return o instanceof LookupOverride || o instanceof ReplaceOverride;
} Prevention
- Use only LookupOverride/ReplaceOverride if targeting native/AOT.
- Audit programmatic method overrides before enabling native builds.
- Avoid inventing MethodOverride subclasses for cross-cutting behavior.
When it happens
Trigger: A bean definition carries a custom subclass of org.springframework.beans.factory.support.MethodOverride that is neither LookupOverride nor ReplaceOverride during AOT code generation.
Common situations: A library or framework registers a bespoke MethodOverride type; programmatic bean definitions that instantiate a MethodOverride subclass directly. This is essentially an internal framework limitation surfacing during native-image/AOT builds.
Related errors
- Unsupported executable: {}
- Argument type mismatch: expected '{}' for value [{}]
- Failed to load Class [{}] from ClassLoader [{}]
- Unsupported executable {}
- {} cannot be found on {}
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/b7c4463354060f36.json.
Report an issue: GitHub.