spring-projects/spring-framework · error · IllegalStateException
'defaultImpl' attribute must be set on DeclareParents
Error message
'defaultImpl' attribute must be set on DeclareParents
What it means
Thrown as an IllegalStateException from ReflectiveAspectJAdvisorFactory.getDeclareParentsAdvisor() when a field annotated with @DeclareParents has its defaultImpl attribute equal to DeclareParents.class (i.e., the attribute was left at its default sentinel value). Spring's introduction (declaration of new parent interfaces) requires either a defaultImpl class or a delegate-ref; without defaultImpl the DeclareParentsAdvisor cannot be constructed.
Solutions
- Set defaultImpl to a concrete class implementing the introduced interface: @DeclareParents(value="...", defaultImpl=FooImpl.class).
- If a delegate bean should provide the implementation, use the XML <aop:declare-parents> with delegate-ref instead of the annotation, or wire the delegate field separately.
- Ensure the chosen defaultImpl class is concrete and implements all introduced interfaces.
Example fix
// before @DeclareParents(value = "com.example.service.*") private UsageTracked[] usageTracked; // defaultImpl left at default -> throws // after @DeclareParents(value = "com.example.service.*", defaultImpl = DefaultUsageTracked.class) private UsageTracked[] usageTracked;
Defensive patterns
Strategy: validation
Validate before calling
import org.aspectj.lang.annotation.DeclareParents;
public static void validateDeclareParentsFields(Class<?> aspectClass) {
for (java.lang.reflect.Field f : aspectClass.getDeclaredFields()) {
DeclareParents dp = f.getAnnotation(DeclareParents.class);
if (dp != null && DeclareParents.class == dp.defaultImpl()) {
throw new IllegalStateException(
"@DeclareParents on " + f + " must set defaultImpl to a concrete class");
}
}
}
Type guard
import org.aspectj.lang.annotation.DeclareParents;
public static boolean declareParentsHasDefaultImpl(DeclareParents dp) {
return dp != null && DeclareParents.class != dp.defaultImpl();
} Try / catch
try {
List<Advisor> advisors = advisorFactory.getAdvisors(factory);
} catch (IllegalStateException ex) {
if (ex.getMessage().contains("defaultImpl")) {
// set defaultImpl on the offending @DeclareParents field
} else throw ex;
} Prevention
- Always set defaultImpl on @DeclareParents to a concrete class implementing the introduced interface.
- If using a delegate, prefer the XML <aop:declare-parents delegate-ref="..."> form.
- Add a reflection-based test that validates all @DeclareParents fields specify defaultImpl.
When it happens
Trigger: An aspect class declaring a field like @DeclareParents(value="com.example..*", defaultImpl=DeclareParents.class) DefaultInterface[] mixins; forgetting to set defaultImpl when the introduction needs a default implementation rather than a delegate.
Common situations: Adding @DeclareParents for an interface introduction but relying on a delegate-ref (delegate-impl) in XML while leaving the annotation's defaultImpl unset in a mixed annotation/XML setup; copy-paste from examples that omit defaultImpl.
Related errors
- Advice must be declared inside an aspect type: Offending…
- 'argumentNames' property of AbstractAspectJAdvice contains…
- is not an @AspectJ aspect
- uses percflow instantiation model: This is not supported in…
- uses percflowbelow instantiation model: This is not…
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/9909b57e840d5df3.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java:192
return methods;
}
/**
* Build a {@link org.springframework.aop.aspectj.DeclareParentsAdvisor}
* for the given introduction field.
* <p>Resulting Advisors will need to be evaluated for targets.
* @param introductionField the field to introspect
* @return the Advisor instance, or {@code null} if not an Advisor
*/
private @Nullable Advisor getDeclareParentsAdvisor(Field introductionField) {
DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);
if (declareParents == null) {
// Not an introduction field
return null;
}
if (DeclareParents.class == declareParents.defaultImpl()) {
throw new IllegalStateException("'defaultImpl' attribute must be set on DeclareParents");
}
return new DeclareParentsAdvisor(
introductionField.getType(), declareParents.value(), declareParents.defaultImpl());
}
@Override
public @Nullable Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}View on GitHub (pinned to 69bf83ad71)