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

  1. Ensure the Method passed to the invocation belongs to the actual target object's class (use AopUtils.getMostSpecificMethod / BridgeMethodResolver).
  2. Do not alter the argument array's length or element types inside advice; if you replace args, keep them type-compatible.
  3. Verify the target bean set on the ProxyFactory/TargetSource is the correct instance type.
  4. 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

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


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)