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
- Make the advice (or its delegate) implement every interface passed to addInterface.
- Use DelegatingIntroductionInterceptor with a delegate object that already implements the interface.
- 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
- Make introduction interceptors implement every introduced interface.
- Use DelegatingIntroductionInterceptor with a delegate that already implements the interface.
- Call validateInterfaces() in a unit test before proxy creation.
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
- DynamicIntroductionAdvice may only be added as part of Intro
- Specified class [{ifc.getName()}] must be an interface
- 'defaultImpl' attribute must be set on DeclareParents
- IntroductionInfo defines no interfaces to introduce: {introd
- Cannot create default implementation for '{interfaceType.get
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/9e455ff165dc1197.json.
Report an issue: GitHub.