spring-projects/spring-framework · error · IllegalArgumentException

DynamicIntroductionAdvice [{advice}] does not implement inte

Error message

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

What it means

DefaultIntroductionAdvisor.validateInterfaces throws IllegalArgumentException when the DynamicIntroductionAdvice does not implement one of the interfaces declared for introduction. The advice is responsible for providing the behaviour of every introduced interface; if it lacks an implementation, the proxy would have unimplemented methods at runtime, so validation rejects it up front.

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

Solutions

  1. Make the advice (or its delegate) implement every interface passed to addInterface.
  2. Use DelegatingIntroductionInterceptor with a delegate object that already implements the interface.
  3. Run advisor.validateInterfaces() in a test to catch mismatches early.

Example fix

// before
public class MyInterceptor extends DelegatingIntroductionInterceptor {
  // does NOT implement Lockable
}
advisor.addInterface(Lockable.class);
advisor.validateInterfaces(); // -> error 118

// after
public class MyInterceptor extends DelegatingIntroductionInterceptor implements Lockable {
  public void lock() { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

for (Class<?> ifc : advisor.getInterfaces()) {
    if (advice instanceof DynamicIntroductionAdvice d && !d.implementsInterface(ifc)) {
        throw new IllegalArgumentException("advice missing interface " + ifc);
    }
}

Type guard

boolean adviceImplements(DynamicIntroductionAdvice advice, Class<?> ifc) {
    return advice != null && ifc != null && advice.implementsInterface(ifc);
}

Prevention

When it happens

Trigger: Constructing a DefaultIntroductionAdvisor(new SomeInterceptor(), NotImplementedInterface.class) where SomeInterceptor does not implement NotImplementedInterface, then the proxy build calls validateInterfaces.

Common situations: Forgetting to add 'implements Lockable' on the introduction interceptor; delegating introduction whose delegate lacks the interface; refactor removing an implements clause without updating the advisor.

Related errors


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