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

  1. Remove the @DeclarePrecedence annotation from the aspect type.
  2. Express ordering using @Order on each aspect class, implementing Ordered, or ordering advice via declaration order within a single aspect.
  3. 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

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


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/1d772c2eb648c07e.json. Report an issue: GitHub.