{"record":{"id":"1d772c2eb648c07e","repo":"spring-projects/spring-framework","slug":"declareprecedence-not-presently-supported-in-sprin","errorCode":null,"errorMessage":"DeclarePrecedence not presently supported in Spring AOP","messagePattern":"DeclarePrecedence not presently supported in Spring AOP","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java","lineNumber":98,"sourceCode":"\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}\n\t\t\tcase PERTYPEWITHIN -> {\n\t\t\t\t// Works with a type pattern\n\t\t\t\tthis.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass)));","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java#L80-L116","documentation":"Thrown as an IllegalArgumentException from the AspectMetadata constructor when ajType.getDeclarePrecedence() returns a non-empty array, i.e., the aspect declares precedence between other aspects (@DeclarePrecedence / declare-precedence). Spring AOP implements aspect ordering via the @Order annotation / Ordered interface instead, so it refuses aspects that use AspectJ's native declare-precedence mechanism.","triggerScenarios":"An aspect class annotated with @DeclarePrecedence (org.aspectj.lang.annotation.DeclarePrecedence) being processed by Spring AOP auto-proxying or AspectMetadata construction; an aspect with a 'declare precedence' statement compiled by ajc and then exposed to Spring AOP.","commonSituations":"Porting an AspectJ-native aspect that orders other aspects via declare-precedence into Spring AOP; copying AspectJ ordering examples that Spring does not support.","solutions":["Remove the @DeclarePrecedence annotation from the aspect.","Express aspect ordering using @Order (or implementing Ordered) on each aspect bean, or via the 'order' attribute in XML config.","If declare-precedence semantics are essential, use AspectJ compile-time or load-time weaving for those aspects."],"exampleFix":"// before\nimport org.aspectj.lang.annotation.DeclarePrecedence;\n\n@Aspect\n@DeclarePrecedence(\"SecurityAspect, LoggingAspect, *\")\npublic class OrderingAspect { ... }\n// after\n@Aspect\n@Order(1)\npublic class SecurityAspect { ... }\n\n@Aspect\n@Order(2)\npublic class LoggingAspect { ... }","handlingStrategy":"validation","validationCode":"import org.aspectj.lang.annotation.Aspect;\nimport org.aspectj.lang.reflect.AjTypeSystem;\n\npublic static boolean hasDeclarePrecedence(Class<?> aspectClass) {\n    return AjTypeSystem.getAjType(aspectClass).getDeclarePrecedence().length > 0;\n}\n\n// before building advisors/metadata for the aspect:\nif (hasDeclarePrecedence(MyAspect.class)) {\n    throw new IllegalStateException(\"@DeclarePrecedence is not supported in Spring AOP; use @Order\");\n}","typeGuard":"import org.aspectj.lang.annotation.DeclarePrecedence;\n\npublic static boolean usesDeclarePrecedence(Class<?> c) {\n    return c.getAnnotation(DeclarePrecedence.class) != null;\n}","tryCatchPattern":"try {\n    AspectMetadata md = new AspectMetadata(clazz, name);\n} catch (IllegalArgumentException ex) {\n    if (ex.getMessage().contains(\"DeclarePrecedence\")) {\n        // remove @DeclarePrecedence and use @Order-based ordering\n    } else throw ex;\n}","preventionTips":["Use @Order / Ordered for aspect ordering in Spring AOP, never @DeclarePrecedence.","Audit imported aspects for declare-precedence usage.","Document ordering conventions in a project guide."],"tags":["spring-aop","aspectj","ordering","configuration"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}