spring-projects/spring-framework · error · IllegalArgumentException
Specified class [ ] must be an interface
Error message
Specified class [{ifc.getName()}] must be an interface What it means
Thrown by DefaultIntroductionAdvisor.addInterface (line 100-103) when the supplied Class is not actually an interface (ifc.isInterface() returns false). Introductions work by making the proxy implement additional interfaces, so passing a concrete class or enum type is a misuse and rejected with an IllegalArgumentException naming the offending class.
Solutions
- Pass an interface type: addInterface(Foo.class) where Foo is an interface, not FooImpl.
- If the type is a class, extract or define an interface it should implement and introduce that interface.
- Double-check the class literal is the interface reference, not the implementation class.
Example fix
// before advisor.addInterface(MyServiceImpl.class); // concrete class // after advisor.addInterface(MyService.class); // interface
Defensive patterns
Strategy: type-guard
Validate before calling
if (!ifc.isInterface()) {
throw new IllegalArgumentException(ifc.getName() + " is not an interface");
}
advisor.addInterface(ifc); Type guard
static boolean isIntroductionInterface(Class<?> c) {
return c != null && c.isInterface();
} Prevention
- Pass interface types only to DefaultIntroductionAdvisor.addInterface.
- Reference the interface class literal, not the implementation class.
- If only a class exists, define and introduce an interface for it.
When it happens
Trigger: Calling addInterface(SomeConcreteClass.class), or constructing DefaultIntroductionAdvisor with a Class argument that is a class rather than an interface. Programmatically adding an introduction with a class reference where an interface was expected.
Common situations: Passing an implementation class instead of its interface (e.g. FooImpl.class instead of Foo.class). Copy-paste from a place that used a class type. Generic Class<?> parameter hiding the interface requirement until runtime.
Related errors
- IntroductionInfo defines no interfaces to introduce
- '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/f979ee65dba2eb13.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java:102
* 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);
}
/**
* Add the specified interface to the list of interfaces to introduce.
* @param ifc the interface to introduce
*/
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");
}
}View on GitHub (pinned to 69bf83ad71)