spring-projects/spring-framework · error · UnsupportedOperationException
An advice method can never be a constructor
Error message
An advice method can never be a constructor
What it means
Thrown by AspectJAdviceParameterNameDiscoverer.getParameterNames(Constructor) (line 288-291) when raiseExceptions is true and a Constructor (rather than a Method) is passed. Advice is by definition a method, never a constructor, so the discoverer refuses to bind constructor parameters; normally it returns null to play nice in the chain-of-responsibility.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java:290
this.numberOfRemainingUnboundArguments + " argument(s) could not be bound");
}
else {
// convention for failing is to return null, allowing participation in a chain of responsibility
return null;
}
}
}
/**
* An advice method can never be a constructor in Spring.
* @return {@code null}
* @throws UnsupportedOperationException if
* {@link #setRaiseExceptions(boolean) raiseExceptions} has been set to {@code true}
*/
@Override
public String @Nullable [] getParameterNames(Constructor<?> ctor) {
if (this.raiseExceptions) {
throw new UnsupportedOperationException("An advice method can never be a constructor");
}
else {
// we return null rather than throw an exception so that we behave well
// in a chain-of-responsibility.
return null;
}
}
private void bindParameterName(int index, @Nullable String name) {
this.parameterNameBindings[index] = name;
this.numberOfRemainingUnboundArguments--;
}
/**
* If the first parameter is of type JoinPoint or ProceedingJoinPoint, bind "thisJoinPoint" as
* parameter name and return true, else return false.
*/View on GitHub (pinned to e8729d0438)
Solutions
- Do not reuse AspectJAdviceParameterNameDiscoverer for constructor introspection; use a standard discoverer (e.g. DefaultParameterNameDiscoverer) for constructors.
- Leave raiseExceptions=false (the default for general use) so it returns null for constructors instead of throwing.
- Scope the discoverer to advice method wiring only.
Example fix
// before: reusing the advice discoverer to inspect a constructor AspectJAdviceParameterNameDiscoverer d = new AspectJAdviceParameterNameDiscoverer(pc); d.setRaiseExceptions(true); String[] names = d.getParameterNames(someConstructor); // after: use a standard discoverer for constructors String[] names = new DefaultParameterNameDiscoverer().getParameterNames(someConstructor);
Defensive patterns
Strategy: validation
Validate before calling
// Do not use AspectJAdviceParameterNameDiscoverer for constructors.
if (member instanceof Constructor<?>) {
throw new IllegalArgumentException(
"Use DefaultParameterNameDiscoverer for constructors; AspectJAdviceParameterNameDiscoverer is method-only");
} Type guard
private static boolean isAdviceMethodCandidate(Member m) {
return m instanceof Method;
} Prevention
- Keep AspectJAdviceParameterNameDiscoverer scoped to advice method wiring only.
- Use DefaultParameterNameDiscoverer for generic (including constructor) parameter name lookups.
- Leave raiseExceptions=false when the discoverer participates in a general chain.
When it happens
Trigger: A ParameterNameDiscoverer chain that includes this discoverer (with raiseExceptions=true) is asked for parameter names of a Constructor. This is unusual for advice wiring; it occurs when the same discoverer instance is reused generically to inspect constructors.
Common situations: Reusing the AspectJAdviceParameterNameDiscoverer outside its intended advice-wiring role (e.g. plugging it into a generic reflection utility that also queries constructors); misconfiguration passing a Constructor to a method-only discoverer.
Related errors
- 'argumentNames' property of AbstractAspectJAdvice contains a
- Only afterReturning advice can be used to bind a return valu
- Returning name '{}' is neither a valid argument name nor the
- Only afterThrowing advice can be used to bind a thrown excep
- Throwing name '{}' is neither a valid argument name nor the
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/c70309fe063963dd.json.
Report an issue: GitHub.