spring-projects/spring-framework · error · IllegalArgumentException
Class [{aspectClass.getName()}] is not a valid aspect type
Error message
Class [{aspectClass.getName()}] is not a valid aspect type What it means
Thrown as an IllegalArgumentException from AspectJProxyFactory.createAspectMetadata() when AspectMetadata construction completes but ajType.isAspect() is false. AspectMetadata walks the class hierarchy looking for an aspect; if none is found it would already throw, so this guard primarily catches edge cases (e.g., an AjType that exists but isAspect() reports false at re-check). Practically it means the class passed to addAspect(...) is not an @AspectJ aspect.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.java:136
* @see AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary(List)
*/
private void addAdvisorsFromAspectInstanceFactory(MetadataAwareAspectInstanceFactory instanceFactory) {
List<Advisor> advisors = this.aspectFactory.getAdvisors(instanceFactory);
Class<?> targetClass = getTargetClass();
Assert.state(targetClass != null, "Unresolvable target class");
advisors = AopUtils.findAdvisorsThatCanApply(advisors, targetClass);
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors);
AnnotationAwareOrderComparator.sort(advisors);
addAdvisors(advisors);
}
/**
* Create an {@link AspectMetadata} instance for the supplied aspect type.
*/
private AspectMetadata createAspectMetadata(Class<?> aspectClass, String aspectName) {
AspectMetadata am = new AspectMetadata(aspectClass, aspectName);
if (!am.getAjType().isAspect()) {
throw new IllegalArgumentException("Class [" + aspectClass.getName() + "] is not a valid aspect type");
}
return am;
}
/**
* Create a {@link MetadataAwareAspectInstanceFactory} for the supplied aspect type. If the aspect type
* has no per clause, then a {@link SingletonMetadataAwareAspectInstanceFactory} is returned, otherwise
* a {@link PrototypeAspectInstanceFactory} is returned.
*/
private MetadataAwareAspectInstanceFactory createAspectInstanceFactory(
AspectMetadata am, Class<?> aspectClass, String aspectName) {
MetadataAwareAspectInstanceFactory instanceFactory;
if (am.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// Create a shared aspect instance.
Object instance = getSingletonAspectInstance(aspectClass);
instanceFactory = new SingletonMetadataAwareAspectInstanceFactory(instance, aspectName);
}View on GitHub (pinned to 69bf83ad71)
Solutions
- Annotate the class with @org.aspectj.lang.annotation.Aspect.
- Double-check you are passing the aspect class/instance, not the target class.
- Ensure the correct class (the one declaring @Before/@Around methods) is supplied to addAspect.
Example fix
// before
AspectJProxyFactory factory = new AspectJProxyFactory(service);
factory.addAspect(LoggingHandler.class); // LoggingHandler has no @Aspect
// after
@Aspect
public class LoggingHandler {
@Before("execution(* com.example.*.*(..))")
public void log() { ... }
}
AspectJProxyFactory factory = new AspectJProxyFactory(service);
factory.addAspect(LoggingHandler.class); Defensive patterns
Strategy: validation
Validate before calling
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.AnnotationUtils;
public static boolean isValidAspectType(Class<?> clazz) {
return AnnotationUtils.findAnnotation(clazz, Aspect.class) != null;
}
// before AspectJProxyFactory.addAspect(clazz):
if (!isValidAspectType(clazz)) {
throw new IllegalArgumentException(clazz + " is not an @AspectJ aspect");
} Type guard
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.AnnotationUtils;
public static boolean isAspectType(Class<?> c) {
return AnnotationUtils.findAnnotation(c, Aspect.class) != null;
} Try / catch
try {
factory.addAspect(candidateClass);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().contains("not a valid aspect type")) {
// annotate the class with @Aspect or pick the correct class
} else throw ex;
} Prevention
- Verify @Aspect is present before calling addAspect; pass the aspect class, not the target.
- Keep aspect classes and target classes in distinct packages to avoid confusion.
- Add a compile-time or test check that aspect classes carry @Aspect.
When it happens
Trigger: Calling AspectJProxyFactory.addAspect(Object) or addAspect(Class) with a class that lacks @Aspect; passing an interface or a plain POJO annotated only with advice annotations (@Before, @Around) but not @Aspect.
Common situations: Forgetting @Aspect on a class passed to the programmatic proxy factory; passing the target class instead of the aspect class by mistake; refactoring that removed @Aspect.
Related errors
- '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
- Expecting to find {} arguments to bind by name in advice, bu
- Not enough arguments in method to satisfy binding of returni
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/feacc5a5941826f4.
Report an issue: GitHub.