{"id":"b87649c79d2c4600","repo":"spring-projects/spring-framework","slug":"uses-percflow-instantiation-model-this-is-not","errorCode":null,"errorMessage":"{} uses percflow instantiation model: This is not supported in Spring AOP.","messagePattern":"(.+?) uses percflow instantiation model: This is not supported in Spring AOP\\.","errorType":"exception","errorClass":"AopConfigException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java","lineNumber":100,"sourceCode":"\tprotected final Log logger = LogFactory.getLog(getClass());\n\n\tprotected final ParameterNameDiscoverer parameterNameDiscoverer = new AspectJAnnotationParameterNameDiscoverer();\n\n\n\t@Override\n\tpublic boolean isAspect(Class<?> clazz) {\n\t\treturn (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null &&\n\t\t\t\t(!shouldIgnoreAjcCompiledAspects || !compiledByAjc(clazz)));\n\t}\n\n\t@Override\n\tpublic void validate(Class<?> aspectClass) throws AopConfigException {\n\t\tAjType<?> ajType = AjTypeSystem.getAjType(aspectClass);\n\t\tif (!ajType.isAspect()) {\n\t\t\tthrow new NotAnAtAspectException(aspectClass);\n\t\t}\n\t\tif (ajType.getPerClause().getKind() == PerClauseKind.PERCFLOW) {\n\t\t\tthrow new AopConfigException(aspectClass.getName() + \" uses percflow instantiation model: \" +\n\t\t\t\t\t\"This is not supported in Spring AOP.\");\n\t\t}\n\t\tif (ajType.getPerClause().getKind() == PerClauseKind.PERCFLOWBELOW) {\n\t\t\tthrow new AopConfigException(aspectClass.getName() + \" uses percflowbelow instantiation model: \" +\n\t\t\t\t\t\"This is not supported in Spring AOP.\");\n\t\t}\n\t}\n\n\n\t/**\n\t * Find and return the first AspectJ annotation on the given method\n\t * (there <i>should</i> only be one anyway...).\n\t */\n\t@SuppressWarnings(\"unchecked\")\n\tprotected static @Nullable AspectJAnnotation findAspectJAnnotationOnMethod(Method method) {\n\t\tfor (Class<?> annotationType : ASPECTJ_ANNOTATION_CLASSES) {\n\t\t\tAspectJAnnotation annotation = findAnnotation(method, (Class<Annotation>) annotationType);\n\t\t\tif (annotation != null) {","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java#L82-L118","documentation":"Thrown by AbstractAspectJAdvisorFactory.validate() when an @AspectJ aspect declares the 'percflow' instantiation model (e.g. @Aspect(\"percflow(...)\")). Spring AOP is proxy-based and runtime-only, so it cannot implement AspectJ's control-flow-scoped aspect instantiation, which requires bytecode weaving. Only singleton (default) and, with caveats, pertarget/perthis/pertypewithin models are supported. Use AspectJ load-time or compile-time weaving (ajc) instead if you truly need percflow semantics.","triggerScenarios":"Calling AspectJProxyFactory.addAspect(), registering an aspect bean processed by AnnotationAwareAspectJAutoProxyCreator, or any path that invokes validate(Class) on a class whose AjType per-clause kind resolves to PerClauseKind.PERCFLOW. This happens when the aspect source carries @Aspect(\"percflow(execution(* com.acme.*.*(..)))\").","commonSituations":"Copying an AspectJ-native aspect (designed for ajc weaving) into a Spring app that only enables @AspectJ auto-proxying. Migrating from full AspectJ to Spring AOP without rewriting the per-clause. Using @EnableAspectJAutoProxy and expecting full AspectJ language coverage.","solutions":["Remove the 'percflow(...)' clause from the @Aspect annotation so the aspect becomes a singleton (the default), which is all Spring AOP supports.","If percflow semantics are genuinely required, switch to AspectJ compile-time weaving (ajc) or load-time weaving (spring-instrument + aop.xml) and remove the aspect from Spring auto-proxying.","Re-express the cflow condition as a regular pointcut expression on a singleton advice method (approximation only; not true control-flow scoping)."],"exampleFix":"// before\n@Aspect(\"percflow(execution(* com.acme..*(..)))\")\npublic class CflowAspect {\n  @Before(\"execution(* com.acme..*(..))\") public void check() { ... }\n}\n// after (Spring AOP compatible)\n@Aspect\npublic class CflowAspect {\n  @Before(\"execution(* com.acme..*(..))\") public void check() { ... }\n}","handlingStrategy":"validation","validationCode":"import org.aspectj.lang.reflect.AjType;\nimport org.aspectj.lang.reflect.AjTypeSystem;\nimport org.aspectj.lang.reflect.PerClauseKind;\n\nvoid ensureSpringAopCompatible(Class<?> aspectClass) {\n  AjType<?> t = AjTypeSystem.getAjType(aspectClass);\n  PerClauseKind k = t.getPerClause().getKind();\n  if (k == PerClauseKind.PERCFLOW) {\n    throw new IllegalStateException(\n      aspectClass + \" uses percflow; switch to singleton or use AspectJ weaving.\");\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Restrict Spring AOP aspects to the default singleton per-clause; never use percflow/percflowbelow.","Keep AspectJ-native aspects in a separate module woven by ajc, not processed by @EnableAspectJAutoProxy.","Add a startup smoke test that validates all @Aspect beans via AbstractAspectJAdvisorFactory.validate()."],"tags":["spring-aop","aspectj","instantiation-model","configuration"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}