spring-projects/spring-framework · error · IllegalStateException
MethodInvocation is not a Spring ProxyMethodInvocation
Error message
MethodInvocation is not a Spring ProxyMethodInvocation: {} What it means
Thrown in AspectJExpressionPointcut.matches(method, targetClass, args) when the current thread-bound MethodInvocation (from ExposeInvocationInterceptor.currentInvocation()) is not a Spring ProxyMethodInvocation. This runtime-args matching path needs the proxy to correctly resolve this() bindings.
Solutions
- Ensure the interceptor chain uses Spring's ReflectiveMethodInvocation / CglibMethodInvocation
- Avoid mixing non-Spring MethodInvocation implementations in Spring-advised proxies
- Register ExposeInvocationInterceptor only within Spring's own proxy infrastructure
Example fix
// before — custom MethodInvocation pushed into ExposeInvocationInterceptor ExposeInvocationInterceptor.currentInvocation() returns non-Spring MI // after — use Spring ProxyMethodInvocation in the chain ReflectiveMethodInvocation springMi = ...; // springMi implements ProxyMethodInvocation
Defensive patterns
Strategy: type-guard
Type guard
// Type guard: check the current invocation is a ProxyMethodInvocation before relying on proxy state
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
MethodInvocation curr = ExposeInvocationInterceptor.currentInvocation();
if (curr instanceof ProxyMethodInvocation pmi) {
Object proxy = pmi.getProxy(); // safe
} else {
// Cannot resolve this() binding — skip or handle gracefully
} Prevention
- Only use ExposeInvocationInterceptor within Spring's own proxy infrastructure
- Do not push non-Spring MethodInvocation objects into the shared invocation thread local
When it happens
Trigger: An interceptor chain that uses ExposeInvocationInterceptor but pushes a non-Spring MethodInvocation into the thread local, or a non-Spring AOP Alliance interceptor running in the same thread as Spring advice matching.
Common situations: Mixing Spring AOP with other AOP Alliance frameworks, or custom MethodInvocation implementations that participate in Spring's ExposeInvocationInterceptor mechanism.
Related errors
- Failed to resolve pointcut expression in
- Invalid expression at location
- MethodInvocation is not a Spring ProxyMethodInvocation
- MethodInvocation is not a Spring ProxyMethodInvocation
- Must set property 'expression' before attempting to match
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/ebd472a50125d95a.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java:359
public boolean isRuntime() {
return obtainPointcutExpression().mayNeedDynamicTest();
}
@Override
public boolean matches(Method method, Class<?> targetClass, @Nullable Object... args) {
ShadowMatch shadowMatch = getTargetShadowMatch(method, targetClass);
// Bind Spring AOP proxy to AspectJ "this" and Spring AOP target to AspectJ target,
// consistent with return of MethodInvocationProceedingJoinPoint
ProxyMethodInvocation pmi = null;
Object targetObject = null;
Object thisObject = null;
try {
MethodInvocation curr = ExposeInvocationInterceptor.currentInvocation();
if (curr.getMethod() == method) {
targetObject = curr.getThis();
if (!(curr instanceof ProxyMethodInvocation currPmi)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + curr);
}
pmi = currPmi;
thisObject = pmi.getProxy();
}
}
catch (IllegalStateException ex) {
// No current invocation...
if (logger.isDebugEnabled()) {
logger.debug("Could not access current invocation - matching with limited context: " + ex);
}
}
try {
JoinPointMatch joinPointMatch = shadowMatch.matchesJoinPoint(thisObject, targetObject, args);
/*
* Do a final check to see if any this(TYPE) kind of residue match. For
* this purpose, we use the original method's (proxy method's) shadow toView on GitHub (pinned to 69bf83ad71)