{"record":{"id":"2d1e05eecdb6998d","repo":"spring-projects/spring-framework","slug":"class-aspectclass-getname-is-not-an-aspectj","errorCode":null,"errorMessage":"Class '{aspectClass.getName()}' 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/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java#L77-L113","documentation":"Thrown as an IllegalArgumentException from the AspectMetadata constructor when walking the class hierarchy (the aspect class and all superclasses up to Object) finds no class whose AjType.isAspect() is true. Unlike AbstractAspectJAdvisorFactory.validate (which only checks the exact class via AjTypeSystem), AspectMetadata walks superclasses, so this fires only when neither the class nor any ancestor is an aspect.","triggerScenarios":"Constructing new AspectMetadata(nonAspectClass, name) directly; indirectly via AspectJProxyFactory, BeanFactoryAspectJAdvisorsBuilder, or any MetadataAwareAspectInstanceFactory when the supplied class (and all its supertypes) lacks @Aspect.","commonSituations":"Supplying a plain bean class to a metadata-driven aspect factory; an aspect base class annotated @Aspect that was loaded by a different classloader so the annotation is invisible; passing an interface or proxy class; stale bytecode where @Aspect was removed.","solutions":["Ensure the class (or a superclass) carries @org.aspectj.lang.annotation.Aspect with RUNTIME retention.","Verify classloader visibility: the @Aspect annotation type and the aspect class must be loaded by the same or ancestor classloader as Spring.","If extending an abstract aspect base, confirm the base class is annotated @Aspect and is on the classpath at runtime."],"exampleFix":"// before\npublic class TxAdvice { ... }\nnew AspectMetadata(TxAdvice.class, \"txAdvice\"); // throws\n// after\n@Aspect\npublic class TxAdvice {\n    @Around(\"execution(* com.example..*.*(..))\")\n    public Object around(ProceedingJoinPoint pjp) throws Throwable { return pjp.proceed(); }\n}","handlingStrategy":"validation","validationCode":"import org.aspectj.lang.annotation.Aspect;\nimport org.aspectj.lang.reflect.AjTypeSystem;\n\npublic static boolean hasAspectInHierarchy(Class<?> clazz) {\n    Class<?> c = clazz;\n    while (c != Object.class) {\n        if (AjTypeSystem.getAjType(c).isAspect()) return true;\n        c = c.getSuperclass();\n    }\n    return false;\n}\n\n// before new AspectMetadata(clazz, name):\nif (!hasAspectInHierarchy(clazz)) {\n    throw new IllegalArgumentException(clazz + \" is not an @AspectJ aspect\");\n}","typeGuard":"import org.aspectj.lang.annotation.Aspect;\nimport org.springframework.core.annotation.AnnotationUtils;\n\npublic static boolean isAtAspectOrInherits(Class<?> c) {\n    return AnnotationUtils.findAnnotation(c, Aspect.class) != null;\n}","tryCatchPattern":"try {\n    AspectMetadata md = new AspectMetadata(clazz, name);\n} catch (IllegalArgumentException ex) {\n    if (ex.getMessage().contains(\"not an @AspectJ aspect\")) {\n        // annotate clazz (or a superclass) with @Aspect\n    } else throw ex;\n}","preventionTips":["Ensure abstract aspect base classes carry @Aspect so subclasses inherit aspect status.","Confirm @Aspect is on the runtime classpath for the context's classloader.","Test aspect metadata construction for all aspect beans at startup."],"tags":["spring-aop","aspectj","configuration","metadata"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}