spring-projects/spring-framework · error · UnsupportedOperationException
Illegal MethodMatcher usage
Error message
Illegal MethodMatcher usage
What it means
StaticMethodMatcher is a convenience base for pointcut matchers that only decide matches at registration time, so isRuntime() is hard-wired to false and the 3-arg matches(Method, Class, Object...) is declared final and throws UnsupportedOperationException. Spring's own AOP runtime always consults isRuntime() before invoking the 3-arg form, so this exception means the 3-arg method was called despite the matcher being static. In practice it signals custom code, a test, or a misbehaving advisor that bypassed the isRuntime() guard.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/support/StaticMethodMatcher.java:41
import org.springframework.aop.MethodMatcher;
/**
* Convenient abstract superclass for static method matchers, which don't care
* about arguments at runtime.
*
* @author Rod Johnson
*/
public abstract class StaticMethodMatcher implements MethodMatcher {
@Override
public final boolean isRuntime() {
return false;
}
@Override
public final boolean matches(Method method, Class<?> targetClass, @Nullable Object... args) {
// should never be invoked because isRuntime() returns false
throw new UnsupportedOperationException("Illegal MethodMatcher usage");
}
}
View on GitHub (pinned to e8729d0438)
Solutions
- Check matcher.isRuntime() before invoking the 3-arg matches(); only call it for DynamicMethodMatcher instances.
- For static matchers use the 2-arg form matches(method, targetClass) which is the method subclasses actually implement.
- If you genuinely need runtime argument matching, extend DynamicMethodMatcher (or implement MethodMatcher directly) instead of StaticMethodMatcher.
Example fix
// before
boolean hit = pointcut.getMethodMatcher().matches(method, beanClass, args);
// after
MethodMatcher mm = pointcut.getMethodMatcher();
boolean hit = mm.isRuntime()
? mm.matches(method, beanClass, args)
: mm.matches(method, beanClass); Defensive patterns
Strategy: type-guard
Validate before calling
MethodMatcher mm = pointcut.getMethodMatcher();
if (mm.isRuntime()) {
// safe to call the 3-arg form
mm.matches(method, beanClass, args);
} else {
// static matcher: use the 2-arg form only
mm.matches(method, beanClass);
} Type guard
static boolean isStaticMatcher(MethodMatcher mm) { return !mm.isRuntime(); } Try / catch
try {
boolean hit = mm.matches(method, beanClass, args);
} catch (UnsupportedOperationException ex) {
if ("Illegal MethodMatcher usage".equals(ex.getMessage())) {
// fall back to 2-arg static matching
hit = mm.matches(method, beanClass);
} else throw ex;
} Prevention
- Always gate the 3-arg matches() behind an isRuntime() check.
- Prefer DynamicMethodMatcher only when you truly need runtime arguments.
- In tests, assert isRuntime() before exercising argument matching.
When it happens
Trigger: Calling matcher.matches(method, targetClass, args) directly on an instance of a StaticMethodMatcher subclass; a custom PointcutAdvisor/Interceptor/IntroductionAdvice that invokes the 3-arg matches() without first checking matcher.isRuntime(); a unit test exercising argument matching on a static matcher.
Common situations: Writing custom AOP utilities or reflection-based pointcut testers; integrating a third-party library that assumes all MethodMatchers are dynamic; upgrading Spring where the 3-arg matches() on StaticMethodMatcher became final and previously-overridden code now hits the superclass.
Related errors
- Cannot invoke methods: {message}
- MethodInvocation is not a Spring ProxyMethodInvocation: {}
- 'argumentNames' property of AbstractAspectJAdvice contains a
- Only afterReturning advice can be used to bind a return valu
- Returning name '{}' is neither a valid argument name nor the
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/1ea0391185cb5402.json.
Report an issue: GitHub.