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
- Make the advice class implement the interface passed to the advisor (or return true from implementsInterface for it).
- Use the one-arg DefaultIntroductionAdvisor(advice) constructor when the advice itself implements IntroductionInfo so interfaces are detected automatically.
- Switch to DelegatingIntroductionInterceptor with a delegate that implements the interface, so the framework derives the interface list from the delegate.
- 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
- Prefer the single-arg DefaultIntroductionAdvisor(advice) when the advice implements IntroductionInfo so interfaces are auto-detected.
- Add a unit test asserting your IntroductionInterceptor.implementsInterface(ifc) returns true for every introduced interface.
- Use DelegatingIntroductionInterceptor to derive the interface list from a concrete delegate.
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
- DynamicIntroductionAdvice may only be added as part of…
- Advisor index is out of bounds: This configuration only has…
- An advice method can never be a constructor
- Cannot add advisor: Configuration is frozen.
- Cannot create default implementation for
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)