{"id":"9e455ff165dc1197","repo":"spring-projects/spring-framework","slug":"dynamicintroductionadvice-advice-does-not-impl","errorCode":null,"errorMessage":"DynamicIntroductionAdvice [{advice}] does not implement interface [{ifc.getName()}] specified for introduction","messagePattern":"DynamicIntroductionAdvice \\[(.+?)\\] does not implement interface \\[(.+?)\\] specified for introduction","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java","lineNumber":117,"sourceCode":"\tpublic void addInterface(Class<?> ifc) {\n\t\tAssert.notNull(ifc, \"Interface must not be null\");\n\t\tif (!ifc.isInterface()) {\n\t\t\tthrow new IllegalArgumentException(\"Specified class [\" + ifc.getName() + \"] must be an interface\");\n\t\t}\n\t\tthis.interfaces.add(ifc);\n\t}\n\n\t@Override\n\tpublic Class<?>[] getInterfaces() {\n\t\treturn ClassUtils.toClassArray(this.interfaces);\n\t}\n\n\t@Override\n\tpublic void validateInterfaces() throws IllegalArgumentException {\n\t\tfor (Class<?> ifc : this.interfaces) {\n\t\t\tif (this.advice instanceof DynamicIntroductionAdvice dynamicIntroductionAdvice &&\n\t\t\t\t\t!dynamicIntroductionAdvice.implementsInterface(ifc)) {\n\t\t\t\tthrow new IllegalArgumentException(\"DynamicIntroductionAdvice [\" + this.advice + \"] \" +\n\t\t\t\t\t\t\"does not implement interface [\" + ifc.getName() + \"] specified for introduction\");\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic void setOrder(int order) {\n\t\tthis.order = order;\n\t}\n\n\t@Override\n\tpublic int getOrder() {\n\t\treturn this.order;\n\t}\n\n\t@Override\n\tpublic Advice getAdvice() {\n\t\treturn this.advice;\n\t}","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java#L99-L135","documentation":"DefaultIntroductionAdvisor.validateInterfaces throws IllegalArgumentException when the DynamicIntroductionAdvice does not implement one of the interfaces declared for introduction. The advice is responsible for providing the behaviour of every introduced interface; if it lacks an implementation, the proxy would have unimplemented methods at runtime, so validation rejects it up front.","triggerScenarios":"Constructing a DefaultIntroductionAdvisor(new SomeInterceptor(), NotImplementedInterface.class) where SomeInterceptor does not implement NotImplementedInterface, then the proxy build calls validateInterfaces.","commonSituations":"Forgetting to add 'implements Lockable' on the introduction interceptor; delegating introduction whose delegate lacks the interface; refactor removing an implements clause without updating the advisor.","solutions":["Make the advice (or its delegate) implement every interface passed to addInterface.","Use DelegatingIntroductionInterceptor with a delegate object that already implements the interface.","Run advisor.validateInterfaces() in a test to catch mismatches early."],"exampleFix":"// before\npublic class MyInterceptor extends DelegatingIntroductionInterceptor {\n  // does NOT implement Lockable\n}\nadvisor.addInterface(Lockable.class);\nadvisor.validateInterfaces(); // -> error 118\n\n// after\npublic class MyInterceptor extends DelegatingIntroductionInterceptor implements Lockable {\n  public void lock() { ... }\n}","handlingStrategy":"validation","validationCode":"for (Class<?> ifc : advisor.getInterfaces()) {\n    if (advice instanceof DynamicIntroductionAdvice d && !d.implementsInterface(ifc)) {\n        throw new IllegalArgumentException(\"advice missing interface \" + ifc);\n    }\n}","typeGuard":"boolean adviceImplements(DynamicIntroductionAdvice advice, Class<?> ifc) {\n    return advice != null && ifc != null && advice.implementsInterface(ifc);\n}","tryCatchPattern":null,"preventionTips":["Make introduction interceptors implement every introduced interface.","Use DelegatingIntroductionInterceptor with a delegate that already implements the interface.","Call validateInterfaces() in a unit test before proxy creation."],"tags":["spring-aop","introduction","type-validation","advisor"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}