spring-projects/spring-framework · error · IllegalArgumentException

MethodInvocation is not a Spring ProxyMethodInvocation

Error message

MethodInvocation is not a Spring ProxyMethodInvocation: {mi}

What it means

Thrown by ExposeBeanNameAdvisors.getBeanName(MethodInvocation) (line 71-73) when the passed MethodInvocation is not an instance of Spring's ProxyMethodInvocation. The bean name is stored as a user attribute on the ProxyMethodInvocation; a generic AOP Alliance MethodInvocation has no user-attribute API, so the lookup cannot proceed and an IllegalArgumentException is raised.

Solutions

  1. Ensure the MethodInvocation you pass is a Spring ProxyMethodInvocation (e.g. ReflectiveMethodInvocation, or the one Spring supplies during proxy invocation).
  2. In tests, pass a mock of ProxyMethodInvocation and stub getUserAttribute/setUserAttribute.
  3. Only invoke getBeanName(mi) from within a Spring-managed proxy chain, not from arbitrary invocation objects.

Example fix

// before
MethodInvocation mi = mock(MethodInvocation.class);
String name = ExposeBeanNameAdvisors.getBeanName(mi); // fails

// after
ProxyMethodInvocation mi = mock(ProxyMethodInvocation.class);
when(mi.getUserAttribute(anyString())).thenReturn("myBean");
String name = ExposeBeanNameAdvisors.getBeanName(mi);
Defensive patterns

Strategy: type-guard

Validate before calling

import org.springframework.aop.ProxyMethodInvocation;
if (!(mi instanceof ProxyMethodInvocation)) {
    throw new IllegalArgumentException("Need a Spring ProxyMethodInvocation");
}

Type guard

static boolean isSpringProxyInvocation(MethodInvocation mi) {
    return mi instanceof ProxyMethodInvocation;
}

Prevention

When it happens

Trigger: Calling ExposeBeanNameAdvisors.getBeanName(mi) where 'mi' is a hand-rolled or third-party MethodInvocation implementation that does not implement org.springframework.aop.ProxyMethodInvocation. This includes unit tests passing a mocked MethodInvocation that is not typed as ProxyMethodInvocation.

Common situations: Unit-testing advice that reads the bean name by passing a plain mock MethodInvocation. Using a non-Spring AOP framework's invocation inside a Spring-advised chain. Calling getBeanName from a thread that received a raw MethodInvocation.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/c47b7e918997ec72. Report an issue: GitHub.

Appendix: source

Thrown at spring-aop/src/main/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisors.java:72

	 * has been included in the interceptor chain, and that the invocation is exposed
	 * with ExposeInvocationInterceptor.
	 * @return the bean name (never {@code null})
	 * @throws IllegalStateException if the bean name has not been exposed
	 */
	public static String getBeanName() throws IllegalStateException {
		return getBeanName(ExposeInvocationInterceptor.currentInvocation());
	}

	/**
	 * Find the bean name for the given invocation. Assumes that an ExposeBeanNameAdvisor
	 * has been included in the interceptor chain.
	 * @param mi the MethodInvocation that should contain the bean name as an attribute
	 * @return the bean name (never {@code null})
	 * @throws IllegalStateException if the bean name has not been exposed
	 */
	public static String getBeanName(MethodInvocation mi) throws IllegalStateException {
		if (!(mi instanceof ProxyMethodInvocation pmi)) {
			throw new IllegalArgumentException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
		}
		String beanName = (String) pmi.getUserAttribute(BEAN_NAME_ATTRIBUTE);
		if (beanName == null) {
			throw new IllegalStateException("Cannot get bean name; not set on MethodInvocation: " + mi);
		}
		return beanName;
	}

	/**
	 * Create a new advisor that will expose the given bean name,
	 * with no introduction.
	 * @param beanName bean name to expose
	 */
	public static Advisor createAdvisorWithoutIntroduction(String beanName) {
		return new DefaultPointcutAdvisor(new ExposeBeanNameInterceptor(beanName));
	}

	/**

View on GitHub (pinned to 69bf83ad71)