{"id":"ebd472a50125d95a","repo":"spring-projects/spring-framework","slug":"methodinvocation-is-not-a-spring-proxymethodinvoca-ebd472","errorCode":null,"errorMessage":"MethodInvocation is not a Spring ProxyMethodInvocation: {}","messagePattern":"MethodInvocation is not a Spring ProxyMethodInvocation: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java","lineNumber":359,"sourceCode":"\tpublic boolean isRuntime() {\n\t\treturn obtainPointcutExpression().mayNeedDynamicTest();\n\t}\n\n\t@Override\n\tpublic boolean matches(Method method, Class<?> targetClass, @Nullable Object... args) {\n\t\tShadowMatch shadowMatch = getTargetShadowMatch(method, targetClass);\n\n\t\t// Bind Spring AOP proxy to AspectJ \"this\" and Spring AOP target to AspectJ target,\n\t\t// consistent with return of MethodInvocationProceedingJoinPoint\n\t\tProxyMethodInvocation pmi = null;\n\t\tObject targetObject = null;\n\t\tObject thisObject = null;\n\t\ttry {\n\t\t\tMethodInvocation curr = ExposeInvocationInterceptor.currentInvocation();\n\t\t\tif (curr.getMethod() == method) {\n\t\t\t\ttargetObject = curr.getThis();\n\t\t\t\tif (!(curr instanceof ProxyMethodInvocation currPmi)) {\n\t\t\t\t\tthrow new IllegalStateException(\"MethodInvocation is not a Spring ProxyMethodInvocation: \" + curr);\n\t\t\t\t}\n\t\t\t\tpmi = currPmi;\n\t\t\t\tthisObject = pmi.getProxy();\n\t\t\t}\n\t\t}\n\t\tcatch (IllegalStateException ex) {\n\t\t\t// No current invocation...\n\t\t\tif (logger.isDebugEnabled()) {\n\t\t\t\tlogger.debug(\"Could not access current invocation - matching with limited context: \" + ex);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tJoinPointMatch joinPointMatch = shadowMatch.matchesJoinPoint(thisObject, targetObject, args);\n\n\t\t\t/*\n\t\t\t * Do a final check to see if any this(TYPE) kind of residue match. For\n\t\t\t * this purpose, we use the original method's (proxy method's) shadow to","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java#L341-L377","documentation":"Thrown inside AspectJExpressionPointcut.matches(method, targetClass, args) when the current MethodInvocation obtained from ExposeInvocationInterceptor is not a ProxyMethodInvocation. The 3-arg matches is invoked at runtime for dynamic (runtime) pointcut checks and needs the proxy reference to bind 'this' correctly.","triggerScenarios":"A runtime (dynamic) pointcut evaluation where the current invocation in the thread-local ExposeInvocationInterceptor is a non-Spring MethodInvocation, e.g. from a third-party interceptor chain or a custom advisory framework plugged into Spring.","commonSituations":"Integrating non-Spring AOP interceptors within a Spring-advised proxy; replacing the default interceptor chain; using Spring AOP infrastructure in an embedded scripting environment that supplies its own invocation.","solutions":["Ensure advice chains run exclusively through Spring's proxy infrastructure so the current invocation is always a ProxyMethodInvocation.","Adapt third-party invocations to ProxyMethodInvocation before exposing them via ExposeInvocationInterceptor.","Avoid mixing non-Spring MethodInvocation types in a Spring-advised object graph."],"exampleFix":"// No user code change typical; ensure the proxy is created by Spring:\n// before: custom invocation pushed into ExposeInvocationInterceptor\n\n// after: use Spring's ProxyFactory to build the proxy\nProxyFactory pf = new ProxyFactory(target);\npf.addAdvice(myInterceptor);\nMyService proxy = (MyService) pf.getProxy();","handlingStrategy":"type-guard","validationCode":"MethodInvocation curr = ExposeInvocationInterceptor.currentInvocation();\nif (!(curr instanceof ProxyMethodInvocation)) {\n    throw new IllegalStateException(\"current invocation must be a ProxyMethodInvocation\");\n}","typeGuard":"boolean ok = ExposeInvocationInterceptor.currentInvocation() instanceof org.springframework.aop.ProxyMethodInvocation;","tryCatchPattern":null,"preventionTips":["Run all advice through Spring-created proxies.","Adapt third-party invocations to ProxyMethodInvocation before exposing them.","Do not push non-Spring invocations into ExposeInvocationInterceptor."],"tags":["spring-aop","aspectj","proxy","runtime-matching"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}