spring-projects/spring-framework · error · IllegalArgumentException
{annotation} is not a valid AspectJ annotation
Error message
{annotation} is not a valid AspectJ annotation What it means
Thrown as an IllegalArgumentException from the AspectJAnnotation constructor when an error occurs while resolving the pointcut expression string from a recognized AspectJ advice annotation (@Pointcut, @Before, @After, @Around, @AfterReturning, @AfterThrowing). The underlying cause (the original exception) is chained. It signals the annotation is structurally present but malformed enough that Spring cannot extract or interpret its pointcut/value attribute.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java:189
private final Annotation annotation;
private final AspectJAnnotationType annotationType;
private final String pointcutExpression;
private final String argumentNames;
public AspectJAnnotation(Annotation annotation) {
this.annotation = annotation;
this.annotationType = determineAnnotationType(annotation);
try {
this.pointcutExpression = resolvePointcutExpression(annotation);
Object argNames = AnnotationUtils.getValue(annotation, "argNames");
this.argumentNames = (argNames instanceof String names ? names : "");
}
catch (Exception ex) {
throw new IllegalArgumentException(annotation + " is not a valid AspectJ annotation", ex);
}
}
private AspectJAnnotationType determineAnnotationType(Annotation annotation) {
AspectJAnnotationType type = annotationTypeMap.get(annotation.annotationType());
if (type != null) {
return type;
}
throw new IllegalStateException("Unknown annotation type: " + annotation);
}
private String resolvePointcutExpression(Annotation annotation) {
for (String attributeName : EXPRESSION_ATTRIBUTES) {
Object val = AnnotationUtils.getValue(annotation, attributeName);
if (val instanceof String str && !str.isEmpty()) {
return str;
}
}View on GitHub (pinned to 69bf83ad71)
Solutions
- Inspect the chained cause exception (getCause()) to find the real reflective failure.
- Ensure the advice annotation is the standard AspectJ annotation and not a custom meta-annotation that interferes with the 'pointcut'/'value' attribute.
- Recompile the aspect class to rule out a stale/corrupt class file.
- Verify the annotation is not being synthesized by a library that breaks AnnotationUtils.getValue semantics.
Defensive patterns
Strategy: try-catch
Validate before calling
import org.springframework.core.annotation.AnnotationUtils;
public static boolean hasResolvablePointcut(java.lang.annotation.Annotation ann) {
for (String attr : new String[]{"pointcut", "value"}) {
Object v = AnnotationUtils.getValue(ann, attr);
if (v instanceof String s && !s.isEmpty()) return true;
}
return false;
}
// validate advice annotations before registering the aspect:
for (Method m : aspectClass.getDeclaredMethods()) {
for (var a : m.getAnnotations()) {
if (isAspectJAdvice(a) && !hasResolvablePointcut(a)) {
throw new IllegalStateException("Advice " + m + " has an unresolvable pointcut");
}
}
} Try / catch
try {
List<Advisor> advisors = advisorFactory.getAdvisors(factory);
} catch (IllegalArgumentException ex) {
if (ex.getCause() != null && ex.getMessage().contains("not a valid AspectJ annotation")) {
// log the offending annotation and cause, skip the aspect
} else throw ex;
} Prevention
- Avoid custom meta-annotations that mask the standard 'value'/'pointcut' attributes of advice annotations.
- Keep aspects' bytecode clean; recompile after editing advice annotations.
- In tests, instantiate the aspect and assert getAdvisors(factory) does not throw for each advice method.
When it happens
Trigger: An advice annotation whose 'pointcut' or 'value' attribute throws on reflective access (e.g., a custom meta-annotation that breaks AnnotationUtils.getValue), or whose attribute accessor misbehaves due to a classloader/annotation-proxy issue. This is reached only after findAspectJAnnotationOnMethod identifies the annotation as one of the six known AspectJ types.
Common situations: Custom meta-annotations wrapping @Around/@Before with unusual attribute merging; annotation proxied via a byte-code tool that does not honor the standard Annotation contract; a corrupt class file; JVM or annotation library version incompatibilities that affect reflective attribute reads.
Related errors
- {aspectClass.getName()} is not an @AspectJ aspect
- Unknown annotation type: {annotation}
- Advice must be declared inside an aspect type: Offending met
- MethodInvocation is not a Spring ProxyMethodInvocation: {}
- 'argumentNames' property of AbstractAspectJAdvice contains a
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/f4850e064f694a2d.
Report an issue: GitHub.