spring-projects/spring-framework · error · IllegalArgumentException

DynamicIntroductionAdvice

Error message

DynamicIntroductionAdvice [{advice}] does not implement interface [{ifc.getName()}] specified for introduction

What it means

Thrown by DefaultIntroductionAdvisor.validateInterfaces() when the configured advice implements DynamicIntroductionAdvice but does not claim to implement one of the interfaces registered for introduction via implementsInterface(ifc). Spring AOP requires a dynamic introduction advice to declare which interfaces it can dispatch, because it routes introduced method calls through the advice itself rather than a separate delegate.

Solutions

  1. Make the advice class implement the interface passed to the advisor (or return true from implementsInterface for it).
  2. Use the one-arg DefaultIntroductionAdvisor(advice) constructor when the advice itself implements IntroductionInfo so interfaces are detected automatically.
  3. Switch to DelegatingIntroductionInterceptor with a delegate that implements the interface, so the framework derives the interface list from the delegate.
  4. Double-check that the interface passed to the constructor exactly matches (same Class<?> reference) what the advice advertises.

Example fix

// before
new DefaultIntroductionAdvisor(myInterceptor, Lockable.class) // myInterceptor does not implement Lockable

// after
public class MyInterceptor implements Lockable, IntroductionInterceptor { ... }
new DefaultIntroductionAdvisor(myInterceptor, Lockable.class);
Defensive patterns

Strategy: validation

Validate before calling

// before building the advisor
Advice advice = ...;
Class<?> ifc = ...;
if (advice instanceof DynamicIntroductionAdvice dia && !dia.implementsInterface(ifc)) {
    throw new IllegalStateException("advice does not implement " + ifc.getName());
}
new DefaultIntroductionAdvisor((DynamicIntroductionAdvice) advice, ifc);

Type guard

static boolean adviceImplements(Advice a, Class<?> ifc) {
    return a instanceof DynamicIntroductionAdvice d && d.implementsInterface(ifc);
}

Prevention

When it happens

Trigger: Constructing new DefaultIntroductionAdvice(advice, ifc) where 'advice' is a DynamicIntroductionAdvice (e.g. a custom IntroductionInterceptor) whose implementsInterface(...) returns false for 'ifc', then the proxy factory calls validateInterfaces() during advisor validation (ProxyFactory.addAdvisor / creation of the proxy).

Common situations: Passing the wrong interface class to the two-arg DefaultIntroductionAdvisor constructor; forgetting to implement IntroductionInfo / the interface on a custom IntroductionInterceptor; a typo in the interface class; mixing up DelegatingIntroductionInterceptor (which auto-detects interfaces from the delegate) with a pure DynamicIntroductionAdvice that must declare its own.

Related errors


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

Appendix: source

Thrown at spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java:117

	public void addInterface(Class<?> ifc) {
		Assert.notNull(ifc, "Interface must not be null");
		if (!ifc.isInterface()) {
			throw new IllegalArgumentException("Specified class [" + ifc.getName() + "] must be an interface");
		}
		this.interfaces.add(ifc);
	}

	@Override
	public Class<?>[] getInterfaces() {
		return ClassUtils.toClassArray(this.interfaces);
	}

	@Override
	public void validateInterfaces() throws IllegalArgumentException {
		for (Class<?> ifc : this.interfaces) {
			if (this.advice instanceof DynamicIntroductionAdvice dynamicIntroductionAdvice &&
					!dynamicIntroductionAdvice.implementsInterface(ifc)) {
				throw new IllegalArgumentException("DynamicIntroductionAdvice [" + this.advice + "] " +
						"does not implement interface [" + ifc.getName() + "] specified for introduction");
			}
		}
	}

	public void setOrder(int order) {
		this.order = order;
	}

	@Override
	public int getOrder() {
		return this.order;
	}

	@Override
	public Advice getAdvice() {
		return this.advice;
	}

View on GitHub (pinned to 69bf83ad71)