spring-projects/spring-framework · error · IllegalArgumentException
IntroductionInfo defines no interfaces to introduce
Error message
IntroductionInfo defines no interfaces to introduce: {introductionInfo} What it means
Thrown by DefaultIntroductionAdvisor constructor (line 71-76) when the supplied IntroductionInfo returns an empty array from getInterfaces(). An introduction must add at least one interface to the proxy so the proxy can implement new behavior; an IntroductionInfo describing zero interfaces is meaningless and rejected with an IllegalArgumentException.
Solutions
- Make your IntroductionInfo.getInterfaces() return at least one interface that the introduction advice actually implements.
- Extend DelegatingIntroductionInterceptor and implement at least one marker/interface method so it exposes that interface.
- If you only need plain advice (not an introduction), use DefaultPointcutAdvisor instead of DefaultIntroductionAdvisor.
Example fix
// before
public class EmptyIntro implements IntroductionInfo {
public Class<?>[] getInterfaces() { return new Class<?>[0]; }
}
new DefaultIntroductionAdvisor(advice, new EmptyIntro()); // fails
// after
public class NamedBeanIntro extends DelegatingIntroductionInterceptor
implements NamedBean {
public String getBeanName() { return "b"; }
}
new DefaultIntroductionAdvisor(new NamedBeanIntro()); Defensive patterns
Strategy: validation
Validate before calling
IntroductionInfo info = /* ... */;
if (info.getInterfaces() == null || info.getInterfaces().length == 0) {
throw new IllegalArgumentException("IntroductionInfo exposes no interfaces");
} Type guard
static boolean hasInterfaces(IntroductionInfo info) {
Class<?>[] c = info.getInterfaces();
return c != null && c.length > 0;
} Prevention
- Implement at least one interface in your DelegatingIntroductionInterceptor subclass.
- Unit-test IntroductionInfo.getInterfaces() to return a non-empty array.
- Use DefaultPointcutAdvisor for plain advice that does not introduce interfaces.
When it happens
Trigger: Constructing 'new DefaultIntroductionAdvisor(advice, introductionInfo)' where the IntroductionInfo.getInterfaces() returns an empty Class[] array. Common with a DelegatingIntroductionInterceptor subclass whose getInterfaces() was overridden/implemented to return nothing, or an IntroductionInfo built from a class exposing no interfaces.
Common situations: Implementing IntroductionInfo and forgetting to populate the interface list. Subclassing DelegatingIntroductionInterceptor but the target introduces no interfaces. Passing an IntroductionInfo whose getInterfaces() is computed dynamically and yields empty under some configuration.
Related errors
- Specified class [ ] must be an interface
- 'defaultImpl' attribute must be set on DeclareParents
- Advice must be declared inside an aspect type: Offending…
- Advice object [ ] is neither a supported subinterface of…
- AdvisorAutoProxyCreator requires a…
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/c29d18bad3815b7a.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java:74
* @see #addInterface
*/
public DefaultIntroductionAdvisor(Advice advice) {
this(advice, (advice instanceof IntroductionInfo introductionInfo ? introductionInfo : null));
}
/**
* Create a DefaultIntroductionAdvisor for the given advice.
* @param advice the Advice to apply
* @param introductionInfo the IntroductionInfo that describes
* the interface to introduce (may be {@code null})
*/
public DefaultIntroductionAdvisor(Advice advice, @Nullable IntroductionInfo introductionInfo) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
if (introductionInfo != null) {
Class<?>[] introducedInterfaces = introductionInfo.getInterfaces();
if (introducedInterfaces.length == 0) {
throw new IllegalArgumentException(
"IntroductionInfo defines no interfaces to introduce: " + introductionInfo);
}
for (Class<?> ifc : introducedInterfaces) {
addInterface(ifc);
}
}
}
/**
* Create a DefaultIntroductionAdvisor for the given advice.
* @param advice the Advice to apply
* @param ifc the interface to introduce
*/
public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> ifc) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
addInterface(ifc);
}View on GitHub (pinned to 69bf83ad71)