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

  1. Annotate the class with @org.aspectj.lang.annotation.Aspect.
  2. Double-check you are passing the aspect class/instance, not the target class.
  3. 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

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


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/feacc5a5941826f4. Report an issue: GitHub.