{"id":"d0632c1246a2d644","repo":"spring-projects/spring-framework","slug":"class-is-not-an-aspectj-aspect","errorCode":null,"errorMessage":"Class '{}' is not an @AspectJ aspect","messagePattern":"Class '(.+?)' is not an @AspectJ aspect","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java","lineNumber":95,"sourceCode":"\t * Create a new AspectMetadata instance for the given aspect class.\n\t * @param aspectClass the aspect class\n\t * @param aspectName the name of the aspect\n\t */\n\tpublic AspectMetadata(Class<?> aspectClass, String aspectName) {\n\t\tthis.aspectName = aspectName;\n\n\t\tClass<?> currClass = aspectClass;\n\t\tAjType<?> ajType = null;\n\t\twhile (currClass != Object.class) {\n\t\t\tAjType<?> ajTypeToCheck = AjTypeSystem.getAjType(currClass);\n\t\t\tif (ajTypeToCheck.isAspect()) {\n\t\t\t\tajType = ajTypeToCheck;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurrClass = currClass.getSuperclass();\n\t\t}\n\t\tif (ajType == null) {\n\t\t\tthrow new IllegalArgumentException(\"Class '\" + aspectClass.getName() + \"' is not an @AspectJ aspect\");\n\t\t}\n\t\tif (ajType.getDeclarePrecedence().length > 0) {\n\t\t\tthrow new IllegalArgumentException(\"DeclarePrecedence not presently supported in Spring AOP\");\n\t\t}\n\t\tthis.aspectClass = ajType.getJavaClass();\n\t\tthis.ajType = ajType;\n\n\t\tswitch (this.ajType.getPerClause().getKind()) {\n\t\t\tcase SINGLETON -> {\n\t\t\t\tthis.perClausePointcut = Pointcut.TRUE;\n\t\t\t}\n\t\t\tcase PERTARGET, PERTHIS -> {\n\t\t\t\tAspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();\n\t\t\t\tajexp.setLocation(aspectClass.getName());\n\t\t\t\tajexp.setExpression(findPerClause(aspectClass));\n\t\t\t\tajexp.setPointcutDeclarationScope(aspectClass);\n\t\t\t\tthis.perClausePointcut = ajexp;\n\t\t\t}","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java#L77-L113","documentation":"Thrown by the AspectMetadata constructor when walking the class hierarchy (the class itself and each superclass up to Object) finds no class that AjTypeSystem reports as an aspect. Every aspect registered with Spring AOP must carry @Aspect (directly or inherited). This fires before any per-clause validation, so it is the first gate an aspect class must pass.","triggerScenarios":"Constructing new AspectMetadata(nonAspectClass, name), triggered by AnnotationAwareAspectJAutoProxyCreator processing a bean whose class is not an @Aspect, or by AspectJProxyFactory/BeanFactoryAspectJAdvisorFactory. Also fires when an @Aspect-annotated interface (not class) is supplied, since AjType only marks classes.","commonSituations":"Registering a bean as an aspect via <aop:aspectj-autoproxy> or @Aspect but the actual bean class is a JDK proxy or lacks the annotation. An aspect annotation imported from the wrong package. An aspect whose @Aspect is on an interface rather than the implementing class.","solutions":["Ensure the concrete class is annotated with @Aspect from org.aspectj.lang.annotation.","Move the @Aspect annotation from an interface onto the implementing class.","Confirm the bean being introspected is the real aspect class, not a proxy or a wrapper."],"exampleFix":"// before\npublic interface Auditable { @Before(\"execution(* *(..))\") void audit(); }\n// after\n@Aspect\npublic class AuditableAspect { @Before(\"execution(* *(..))\") public void audit() {} }","handlingStrategy":"validation","validationCode":"import org.aspectj.lang.reflect.AjTypeSystem;\n\nvoid ensureRecognizedAspect(Class<?> c) {\n  Class<?> cur = c;\n  while (cur != Object.class) {\n    if (AjTypeSystem.getAjType(cur).isAspect()) return;\n    cur = cur.getSuperclass();\n  }\n  throw new IllegalArgumentException(c + \" is not an @AspectJ aspect\");\n}","typeGuard":"boolean isAspectJAspect(Class<?> c) {\n  Class<?> cur = c;\n  while (cur != Object.class) {\n    if (AjTypeSystem.getAjType(cur).isAspect()) return true;\n    cur = cur.getSuperclass();\n  }\n  return false;\n}","tryCatchPattern":null,"preventionTips":["Put @Aspect on the concrete class, not an interface.","Import @Aspect from org.aspectj.lang.annotation, not a custom package.","Add a bean-factory post-processor that asserts every aspect bean resolves as an AjType aspect."],"tags":["spring-aop","aspectj","configuration","validation"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}