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

  1. Set defaultImpl to a concrete class implementing the introduced interface: @DeclareParents(value="...", defaultImpl=FooImpl.class).
  2. 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.
  3. 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

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


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)