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
- Ensure the concrete class is annotated with @Aspect from org.aspectj.lang.annotation.
- Move the @Aspect annotation from an interface onto the implementing class.
- 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
- Put @Aspect on the concrete class, not an interface.
- Import @Aspect from org.aspectj.lang.annotation, not a custom package.
- Add a bean-factory post-processor that asserts every aspect bean resolves as an AjType aspect.
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
- 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/d0632c1246a2d644.json.
Report an issue: GitHub.