spring-projects/spring-framework · error · IllegalArgumentException
DeclarePrecedence not presently supported in Spring AOP
Error message
DeclarePrecedence not presently supported in Spring AOP
What it means
Thrown by the AspectMetadata constructor when the resolved AjType declares one or more declare-precedence statements (@DeclarePrecedence). Spring AOP does not implement AspectJ's declare-precedence (ordering across aspects via pointcut patterns); it only supports @Order / Ordered / advice declaration order. This is a deliberate, long-standing limitation.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java:98
*/
public AspectMetadata(Class<?> aspectClass, String aspectName) {
this.aspectName = aspectName;
Class<?> currClass = aspectClass;
AjType<?> ajType = null;
while (currClass != Object.class) {
AjType<?> ajTypeToCheck = AjTypeSystem.getAjType(currClass);
if (ajTypeToCheck.isAspect()) {
ajType = ajTypeToCheck;
break;
}
currClass = currClass.getSuperclass();
}
if (ajType == null) {
throw new IllegalArgumentException("Class '" + aspectClass.getName() + "' is not an @AspectJ aspect");
}
if (ajType.getDeclarePrecedence().length > 0) {
throw new IllegalArgumentException("DeclarePrecedence not presently supported in Spring AOP");
}
this.aspectClass = ajType.getJavaClass();
this.ajType = ajType;
switch (this.ajType.getPerClause().getKind()) {
case SINGLETON -> {
this.perClausePointcut = Pointcut.TRUE;
}
case PERTARGET, PERTHIS -> {
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setLocation(aspectClass.getName());
ajexp.setExpression(findPerClause(aspectClass));
ajexp.setPointcutDeclarationScope(aspectClass);
this.perClausePointcut = ajexp;
}
case PERTYPEWITHIN -> {
// Works with a type pattern
this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass)));View on GitHub (pinned to e8729d0438)
Solutions
- Remove the @DeclarePrecedence annotation from the aspect type.
- Express ordering using @Order on each aspect class, implementing Ordered, or ordering advice via declaration order within a single aspect.
- If declare-precedence semantics are essential, use AspectJ compile-time or load-time weaving.
Example fix
// before
@Aspect
@DeclarePrecedence("com.acme.SecurityAspect, com.acme.LoggingAspect")
public class OrderingAspect { ... }
// after
@Aspect
@Order(1)
public class SecurityAspect { ... }
@Aspect
@Order(2)
public class LoggingAspect { ... } Defensive patterns
Strategy: validation
Validate before calling
import org.aspectj.lang.reflect.AjTypeSystem;
void ensureNoDeclarePrecedence(Class<?> aspectClass) {
if (AjTypeSystem.getAjType(aspectClass).getDeclarePrecedence().length > 0)
throw new IllegalStateException(aspectClass + " uses @DeclarePrecedence, unsupported by Spring AOP");
} Prevention
- Use @Order / Ordered for cross-aspect ordering in Spring AOP; never @DeclarePrecedence.
- Reserve declare-precedence for AspectJ-woven modules.
When it happens
Trigger: Processing an aspect class annotated @Aspect with @DeclarePrecedence("com.acme.* , com.other.*") on the type, via any path that builds AspectMetadata (auto-proxy creator, AspectJProxyFactory, BeanFactoryAspectJAdvisorFactory).
Common situations: Porting a full AspectJ aspect that uses declare precedence into Spring AOP. Expecting cross-aspect pattern-based ordering to work under @EnableAspectJAutoProxy.
Related errors
- MethodInvocation is not a Spring ProxyMethodInvocation: {}
- 'argumentNames' property of AbstractAspectJAdvice contains a
- Only afterReturning advice can be used to bind a return valu
- Only afterThrowing advice can be used to bind a thrown excep
- Advice method [{}] requires {} arguments to be bound by name
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/1d772c2eb648c07e.json.
Report an issue: GitHub.