spring-projects/spring-framework · error · IllegalArgumentException

Class '{}' is not an @AspectJ aspect

Error message

Class '{}' is not an @AspectJ aspect

What it means

Thrown by the AspectMetadata constructor when walking the class hierarchy (the class itself and each superclass up to Object) finds no class that AjTypeSystem reports as an aspect. Every aspect registered with Spring AOP must carry @Aspect (directly or inherited). This fires before any per-clause validation, so it is the first gate an aspect class must pass.

Source

Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java:95

	 * Create a new AspectMetadata instance for the given aspect class.
	 * @param aspectClass the aspect class
	 * @param aspectName the name of the aspect
	 */
	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;
			}

View on GitHub (pinned to e8729d0438)

Solutions

  1. Ensure the concrete class is annotated with @Aspect from org.aspectj.lang.annotation.
  2. Move the @Aspect annotation from an interface onto the implementing class.
  3. Confirm the bean being introspected is the real aspect class, not a proxy or a wrapper.

Example fix

// before
public interface Auditable { @Before("execution(* *(..))") void audit(); }
// after
@Aspect
public class AuditableAspect { @Before("execution(* *(..))") public void audit() {} }
Defensive patterns

Strategy: validation

Validate before calling

import org.aspectj.lang.reflect.AjTypeSystem;

void ensureRecognizedAspect(Class<?> c) {
  Class<?> cur = c;
  while (cur != Object.class) {
    if (AjTypeSystem.getAjType(cur).isAspect()) return;
    cur = cur.getSuperclass();
  }
  throw new IllegalArgumentException(c + " is not an @AspectJ aspect");
}

Type guard

boolean isAspectJAspect(Class<?> c) {
  Class<?> cur = c;
  while (cur != Object.class) {
    if (AjTypeSystem.getAjType(cur).isAspect()) return true;
    cur = cur.getSuperclass();
  }
  return false;
}

Prevention

When it happens

Trigger: Constructing new AspectMetadata(nonAspectClass, name), triggered by AnnotationAwareAspectJAutoProxyCreator processing a bean whose class is not an @Aspect, or by AspectJProxyFactory/BeanFactoryAspectJAdvisorFactory. Also fires when an @Aspect-annotated interface (not class) is supplied, since AjType only marks classes.

Common situations: Registering a bean as an aspect via <aop:aspectj-autoproxy> or @Aspect but the actual bean class is a JDK proxy or lacks the annotation. An aspect annotation imported from the wrong package. An aspect whose @Aspect is on an interface rather than the implementing class.

Related errors


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