spring-projects/spring-framework · error · IllegalArgumentException

MethodInvocation is not a Spring ProxyMethodInvocation: {mi}

Error message

MethodInvocation is not a Spring ProxyMethodInvocation: {mi}

What it means

ExposeBeanNameAdvisors.getBeanName(MethodInvocation) throws IllegalArgumentException when the supplied invocation is not a Spring ProxyMethodInvocation. The bean-name mechanism stores the name as a user attribute via pmi.setUserAttribute, an API only ProxyMethodInvocation exposes; a generic AOP Alliance MethodInvocation cannot carry it.

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 e8729d0438)

Solutions

  1. Ensure the invocation originates from a Spring-generated proxy (ProxyFactory, ProxyFactoryBean, or a Spring bean proxy).
  2. If you must call getBeanName, obtain the invocation via ExposeInvocationInterceptor.currentInvocation() which Spring populates.
  3. Do not pass custom MethodInvocation implementations into ExposeBeanNameAdvisors.

Example fix

// before
MethodInvocation mi = myCustomAopAllianceInvocation;
String name = ExposeBeanNameAdvisors.getBeanName(mi); // not a ProxyMethodInvocation

// after
MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation();
String name = ExposeBeanNameAdvisors.getBeanName(mi);
Defensive patterns

Strategy: type-guard

Type guard

boolean isSpringInvocation(org.aopalliance.intercept.MethodInvocation mi) {
    return mi instanceof org.springframework.aop.ProxyMethodInvocation;
}

Try / catch

try {
    String name = ExposeBeanNameAdvisors.getBeanName(mi);
} catch (IllegalArgumentException ex) {
    // invocation is not a Spring ProxyMethodInvocation; fall back to another strategy
}

Prevention

When it happens

Trigger: Calling ExposeBeanNameAdvisors.getBeanName(mi) where mi is a hand-rolled or third-party AOP Alliance MethodInvocation that does not implement org.springframework.aop.ProxyMethodInvocation.

Common situations: Interoperating Spring AOP with another AOP Alliance implementation; unit tests passing a mocked MethodInvocation; mixing in non-Spring proxies.

Related errors


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/c47b7e918997ec72.json. Report an issue: GitHub.