spring-projects/spring-framework · error · AopConfigException
DynamicIntroductionAdvice may only be added as part of…
Error message
DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor
What it means
addAdvice(int, Advice) (line 435) handles three branches: IntroductionInfo (self-describing), DynamicIntroductionAdvice, and plain advice. A DynamicIntroductionAdvice (e.g. a per-instance introduction mixin) carries introduction state and must be registered through an IntroductionAdvisor so its interfaces are validated and added. Registering it as plain advice is rejected (line 444).
Solutions
- Wrap the introduction advice in an IntroductionAdvisor: advised.addAdvisor(new DefaultIntroductionAdvisor(advice, introductionInfo))
- If the advice implements IntroductionInfo too, addAdvice can work via that branch - otherwise always use an IntroductionAdvisor
- Review the advice type: anything that is a DynamicIntroductionAdvice must go through an advisor
Example fix
// before advised.addAdvice(myDelegatingIntroductionInterceptor); // after advised.addAdvisor(new DefaultIntroductionAdvisor(myDelegatingIntroductionInterceptor));
Defensive patterns
Strategy: type-guard
Validate before calling
if (advice instanceof DynamicIntroductionAdvice) {
throw new IllegalStateException("Use addAdvisor(new DefaultIntroductionAdvisor(advice)) for introduction advice");
} Type guard
private static boolean isPlainAdvice(Advice advice) {
return advice != null && !(advice instanceof DynamicIntroductionAdvice);
} Prevention
- Always route DynamicIntroductionAdvice through an IntroductionAdvisor
- Check instanceof before addAdvice when the advice source is dynamic
When it happens
Trigger: Passing an instance whose class implements org.springframework.aop.DynamicIntroductionAdvice to addAdvice() directly, instead of wrapping it in an IntroductionAdvisor (e.g. DefaultIntroductionAdvisor).
Common situations: Trying to add a DelegatingIntroductionInterceptor or similar mixin via addAdvice(...) rather than addAdvisor(new DefaultIntroductionAdvisor(advice)); mixing up the addAdvice and addAdvisor entry points.
Related errors
- Advisor index is out of bounds: This configuration only has…
- Cannot add advisor: Configuration is frozen.
- Cannot remove Advisor: Configuration is frozen.
- DynamicIntroductionAdvice
- Illegal position in advisor list with size
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/f758ec5beb859e92.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java:444
public void addAdvice(Advice advice) throws AopConfigException {
int pos = this.advisors.size();
addAdvice(pos, advice);
}
/**
* Cannot add introductions this way unless the advice implements IntroductionInfo.
*/
@Override
public void addAdvice(int pos, Advice advice) throws AopConfigException {
Assert.notNull(advice, "Advice must not be null");
if (advice instanceof IntroductionInfo introductionInfo) {
// We don't need an IntroductionAdvisor for this kind of introduction:
// It's fully self-describing.
addAdvisor(pos, new DefaultIntroductionAdvisor(advice, introductionInfo));
}
else if (advice instanceof DynamicIntroductionAdvice) {
// We need an IntroductionAdvisor for this kind of introduction.
throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor");
}
else {
addAdvisor(pos, new DefaultPointcutAdvisor(advice));
}
}
@Override
public boolean removeAdvice(Advice advice) throws AopConfigException {
int index = indexOf(advice);
if (index == -1) {
return false;
}
else {
removeAdvisor(index);
return true;
}
}
View on GitHub (pinned to 69bf83ad71)