spring-projects/spring-framework · error · AopInvocationException
AOP configuration seems to be invalid: tried calling method
Error message
AOP configuration seems to be invalid: tried calling method [{method}] on target [{target}] What it means
Thrown by AopUtils.invokeJoinpointUsingReflection (line 366-368) when Method.invoke raises an IllegalArgumentException. This happens when the method's declaring class does not match the target object's class, or the supplied argument array's types/counts do not match the method signature. The reflection error is wrapped in an AopInvocationException that names the method and target.
Solutions
- Ensure the Method passed to the invocation belongs to the actual target object's class (use AopUtils.getMostSpecificMethod / BridgeMethodResolver).
- Do not alter the argument array's length or element types inside advice; if you replace args, keep them type-compatible.
- Verify the target bean set on the ProxyFactory/TargetSource is the correct instance type.
- Check for bridge-method resolution issues by logging method + target class to spot a class mismatch.
Example fix
// before // target swapped to an incompatible instance proxyFactory.setTarget(new SomeOtherService()); method.invoke(wrongTarget, args); // -> AOP config invalid // after proxyFactory.setTarget(realServiceInstance); Method m = AopUtils.getMostSpecificMethod(method, realServiceInstance.getClass()); m.invoke(realServiceInstance, args);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!method.getDeclaringClass().isInstance(target)
&& !method.getDeclaringClass().isAssignableFrom(target.getClass())) {
// method does not match target class; resolve via getMostSpecificMethod
} Try / catch
try {
return AopUtils.invokeJoinpointUsingReflection(target, method, args);
} catch (AopInvocationException e) {
// re-resolve method against the real target class and retry once
Method resolved = AopUtils.getMostSpecificMethod(method, target.getClass());
return AopUtils.invokeJoinpointUsingReflection(target, resolved, args);
} Prevention
- Always resolve the method against the actual target class before reflection invocation.
- Do not mutate the argument array length or incompatible types inside advice.
- Keep the target object consistent with the method's declaring class.
When it happens
Trigger: An AOP interceptor calls invokeJoinpointUsingReflection with a Method obtained from a different class than 'target', or with mismatched args (wrong count, incompatible types, null for a primitive). Common when a proxy target is swapped, when bridged/generic methods are mishandled, or when an interceptor tampers with the argument array.
Common situations: Swapping the target object behind a proxy to an instance whose class does not declare the method. Modifying the arguments array length or types inside an advice. Generic/bridge method edge cases where the resolved Method belongs to a superclass/interface. Misconfigured interceptor that passes a Method from the wrong class.
Related errors
- is not a valid AspectJ annotation
- At least one handler method must be found in class
- Cannot create default implementation for
- Could not access method
- MethodInvocation is not a Spring ProxyMethodInvocation
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/2fb61baf40a6bd81.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java:367
* @throws org.springframework.aop.AopInvocationException in case of a reflection error
*/
public static @Nullable Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, @Nullable Object[] args)
throws Throwable {
// Use reflection to invoke the method.
try {
Method originalMethod = BridgeMethodResolver.findBridgedMethod(method);
ReflectionUtils.makeAccessible(originalMethod);
return (COROUTINES_REACTOR_PRESENT && KotlinDetector.isSuspendingFunction(originalMethod) ?
KotlinDelegate.invokeSuspendingFunction(originalMethod, target, args) : originalMethod.invoke(target, args));
}
catch (InvocationTargetException ex) {
// Invoked method threw a checked exception.
// We must rethrow it. The client won't see the interceptor.
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException | InaccessibleObjectException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}
/**
* Inner class to avoid a hard dependency on Kotlin at runtime.
*/
private static class KotlinDelegate {
public static Object invokeSuspendingFunction(Method method, @Nullable Object target, @Nullable Object... args) {
Continuation<?> continuation = (Continuation<?>) args[args.length -1];
Assert.state(continuation != null, "No Continuation available");
CoroutineContext context = continuation.getContext().minusKey(Job.Key);
return CoroutinesUtils.invokeSuspendingFunction(context, method, target, args);View on GitHub (pinned to 69bf83ad71)