{"id":"1ea0391185cb5402","repo":"spring-projects/spring-framework","slug":"illegal-methodmatcher-usage","errorCode":null,"errorMessage":"Illegal MethodMatcher usage","messagePattern":"Illegal MethodMatcher usage","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/support/StaticMethodMatcher.java","lineNumber":41,"sourceCode":"import org.springframework.aop.MethodMatcher;\n\n/**\n * Convenient abstract superclass for static method matchers, which don't care\n * about arguments at runtime.\n *\n * @author Rod Johnson\n */\npublic abstract class StaticMethodMatcher implements MethodMatcher {\n\n\t@Override\n\tpublic final boolean isRuntime() {\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic final boolean matches(Method method, Class<?> targetClass, @Nullable Object... args) {\n\t\t// should never be invoked because isRuntime() returns false\n\t\tthrow new UnsupportedOperationException(\"Illegal MethodMatcher usage\");\n\t}\n\n}\n","sourceCodeStart":23,"sourceCodeEnd":45,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/support/StaticMethodMatcher.java#L23-L45","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nboolean hit = pointcut.getMethodMatcher().matches(method, beanClass, args);\n\n// after\nMethodMatcher mm = pointcut.getMethodMatcher();\nboolean hit = mm.isRuntime()\n    ? mm.matches(method, beanClass, args)\n    : mm.matches(method, beanClass);","handlingStrategy":"type-guard","validationCode":"MethodMatcher mm = pointcut.getMethodMatcher();\nif (mm.isRuntime()) {\n    // safe to call the 3-arg form\n    mm.matches(method, beanClass, args);\n} else {\n    // static matcher: use the 2-arg form only\n    mm.matches(method, beanClass);\n}","typeGuard":"static boolean isStaticMatcher(MethodMatcher mm) { return !mm.isRuntime(); }","tryCatchPattern":"try {\n    boolean hit = mm.matches(method, beanClass, args);\n} catch (UnsupportedOperationException ex) {\n    if (\"Illegal MethodMatcher usage\".equals(ex.getMessage())) {\n        // fall back to 2-arg static matching\n        hit = mm.matches(method, beanClass);\n    } else throw ex;\n}","preventionTips":["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."],"tags":["spring-aop","method-matcher","aop","unsupported-operation"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}