{"record":{"id":"9909b57e840d5df3","repo":"spring-projects/spring-framework","slug":"defaultimpl-attribute-must-be-set-on-declarepare","errorCode":null,"errorMessage":"'defaultImpl' attribute must be set on DeclareParents","messagePattern":"'defaultImpl' attribute must be set on DeclareParents","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java","lineNumber":192,"sourceCode":"\t\treturn methods;\n\t}\n\n\t/**\n\t * Build a {@link org.springframework.aop.aspectj.DeclareParentsAdvisor}\n\t * for the given introduction field.\n\t * <p>Resulting Advisors will need to be evaluated for targets.\n\t * @param introductionField the field to introspect\n\t * @return the Advisor instance, or {@code null} if not an Advisor\n\t */\n\tprivate @Nullable Advisor getDeclareParentsAdvisor(Field introductionField) {\n\t\tDeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);\n\t\tif (declareParents == null) {\n\t\t\t// Not an introduction field\n\t\t\treturn null;\n\t\t}\n\n\t\tif (DeclareParents.class == declareParents.defaultImpl()) {\n\t\t\tthrow new IllegalStateException(\"'defaultImpl' attribute must be set on DeclareParents\");\n\t\t}\n\n\t\treturn new DeclareParentsAdvisor(\n\t\t\t\tintroductionField.getType(), declareParents.value(), declareParents.defaultImpl());\n\t}\n\n\n\t@Override\n\tpublic @Nullable Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,\n\t\t\tint declarationOrderInAspect, String aspectName) {\n\n\t\tvalidate(aspectInstanceFactory.getAspectMetadata().getAspectClass());\n\n\t\tAspectJExpressionPointcut expressionPointcut = getPointcut(\n\t\t\t\tcandidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());\n\t\tif (expressionPointcut == null) {\n\t\t\treturn null;\n\t\t}","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java#L174-L210","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n@DeclareParents(value = \"com.example.service.*\")\nprivate UsageTracked[] usageTracked; // defaultImpl left at default -> throws\n// after\n@DeclareParents(value = \"com.example.service.*\", defaultImpl = DefaultUsageTracked.class)\nprivate UsageTracked[] usageTracked;","handlingStrategy":"validation","validationCode":"import org.aspectj.lang.annotation.DeclareParents;\n\npublic static void validateDeclareParentsFields(Class<?> aspectClass) {\n    for (java.lang.reflect.Field f : aspectClass.getDeclaredFields()) {\n        DeclareParents dp = f.getAnnotation(DeclareParents.class);\n        if (dp != null && DeclareParents.class == dp.defaultImpl()) {\n            throw new IllegalStateException(\n                \"@DeclareParents on \" + f + \" must set defaultImpl to a concrete class\");\n        }\n    }\n}\n","typeGuard":"import org.aspectj.lang.annotation.DeclareParents;\n\npublic static boolean declareParentsHasDefaultImpl(DeclareParents dp) {\n    return dp != null && DeclareParents.class != dp.defaultImpl();\n}","tryCatchPattern":"try {\n    List<Advisor> advisors = advisorFactory.getAdvisors(factory);\n} catch (IllegalStateException ex) {\n    if (ex.getMessage().contains(\"defaultImpl\")) {\n        // set defaultImpl on the offending @DeclareParents field\n    } else throw ex;\n}","preventionTips":["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."],"tags":["spring-aop","aspectj","introduction","declare-parents","configuration"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}