{"record":{"id":"71a65e5ba22f2c8d","repo":"spring-projects/spring-framework","slug":"ifc-getname-is-not-an-interface","errorCode":null,"errorMessage":"[{ifc.getName()}] is not an interface","messagePattern":"\\[(.+?)\\] is not an interface","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java","lineNumber":234,"sourceCode":"\t/**\n\t * Set the interfaces to be proxied.\n\t */\n\tpublic void setInterfaces(Class<?>... interfaces) {\n\t\tAssert.notNull(interfaces, \"Interfaces must not be null\");\n\t\tthis.interfaces.clear();\n\t\tfor (Class<?> ifc : interfaces) {\n\t\t\taddInterface(ifc);\n\t\t}\n\t}\n\n\t/**\n\t * Add a new proxied interface.\n\t * @param ifc the additional interface to proxy\n\t */\n\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(\"[\" + ifc.getName() + \"] is not an interface\");\n\t\t}\n\t\tif (!this.interfaces.contains(ifc)) {\n\t\t\tthis.interfaces.add(ifc);\n\t\t\tadviceChanged();\n\t\t}\n\t}\n\n\t/**\n\t * Remove a proxied interface.\n\t * <p>Does nothing if the given interface isn't proxied.\n\t * @param ifc the interface to remove from the proxy\n\t * @return {@code true} if the interface was removed; {@code false}\n\t * if the interface was not found and hence could not be removed\n\t */\n\tpublic boolean removeInterface(Class<?> ifc) {\n\t\treturn this.interfaces.remove(ifc);\n\t}\n","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java#L216-L252","documentation":"AdvisedSupport.addInterface() (line 231) registers an interface to be proxied. It guards with ifc.isInterface() (line 233) and throws if a concrete class (or enum, etc.) is passed. JDK/CGLIB proxies expose interfaces, so adding a non-interface is a user error.","triggerScenarios":"Calling addInterface(SomeConcreteClass.class) or setInterfaces(SomeConcreteClass.class); XML/java config that lists a class instead of an interface among proxyInterfaces.","commonSituations":"Confusing the proxy-target-class (CGLIB subclassing) concept with the interface list; passing the implementation class where the interface was intended; migrating from proxyTargetClass=true and mistakenly adding the impl class to setInterfaces.","solutions":["Pass an actual interface type, e.g. addInterface(MyService.class) where MyService is an interface","If you intended to proxy a concrete class, use setProxyTargetClass(true) / proxyTargetClass=\"true\" instead of adding the class as an interface","Double-check the types array passed to setInterfaces(...) contains only interfaces"],"exampleFix":"// before\nadvised.addInterface(MyServiceImpl.class);\n\n// after\nadvised.addInterface(MyService.class);  // MyService is the interface","handlingStrategy":"type-guard","validationCode":"if (ifc != null && !ifc.isInterface()) {\n  throw new IllegalStateException(ifc.getName() + \" is not an interface; use proxyTargetClass for class proxying\");\n}","typeGuard":"private static boolean isProxiableInterface(Class<?> ifc) {\n  return ifc != null && ifc.isInterface();\n}","tryCatchPattern":null,"preventionTips":["Filter any class list through Class::isInterface before calling setInterfaces/addInterface","Use setProxyTargetClass(true) when you need to proxy a concrete class"],"tags":["spring-aop","advised","interface","config"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}