spring-projects/spring-framework · error · IllegalStateException
Failed to find advice method on deserialization
Error message
Failed to find advice method on deserialization
What it means
Thrown by readObject (line 696-704) during Java deserialization of an AbstractAspectJAdvice subclass. The method is marked transient (line 100) so on deserialization Spring re-looks-up the advice Method via declaringClass.getMethod(methodName, parameterTypes). If that lookup throws NoSuchMethodException, the aspect's bytecode no longer matches what was serialized.
Solutions
- Ensure the aspect class (same fully-qualified name, same method name and parameter types) is on the classpath of the deserializing JVM.
- Do not serialize Spring AOP proxies across versions; rebuild the proxy on the receiving side instead.
- If the aspect method changed, re-serialize after the change so the methodName/parameterTypes fields match.
- Use the same ClassLoader hierarchy on both ends, or avoid serializing advice objects entirely.
Example fix
// before — serializing a proxied bean across a redeploy that renamed the advice method ObjectOutputStream out = ...; out.writeObject(proxy); // method was 'logBefore' // redeploy renames method to 'auditBefore' -> deserialization fails // after — rebuild the proxy on the receiving JVM instead of serializing advice objects MyService proxy = new AspectJProxyFactory(target).addAspect(auditAspect).getProxy();
Defensive patterns
Strategy: validation
Validate before calling
import java.lang.reflect.Method;
// Before deserializing, confirm the advice method still exists with the same signature.
boolean adviceMethodResolvable(Class<?> declaringClass, String methodName, Class<?>[] paramTypes) {
try {
Method m = declaringClass.getMethod(methodName, paramTypes);
return m != null;
} catch (NoSuchMethodException e) {
return false;
}
} Type guard
boolean adviceMethodExists(Class<?> declaringClass, String methodName, Class<?>[] paramTypes) {
try { declaringClass.getMethod(methodName, paramTypes); return true; }
catch (NoSuchMethodException e) { return false; }
} Try / catch
try (ObjectInputStream in = new ObjectInputStream(input)) {
Object proxy = in.readObject();
} catch (IllegalStateException ex) {
if (ex.getMessage().contains("Failed to find advice method on deserialization")) {
// aspect method renamed/removed; rebuild the proxy locally instead of deserializing
} else { throw ex; }
} Prevention
- Do not serialize Spring AOP proxies across deployments; reconstruct them on each JVM.
- Keep aspect class/method/parameter signatures stable across versions that share serialized forms.
- Use the same ClassLoader hierarchy on both ends if serialization is unavoidable.
When it happens
Trigger: Serializing an aspect/advice in one deployment and deserializing in another where the aspect class was renamed, its method was renamed/signature changed, or the class version differs. Also if the declaring class is loaded by a different ClassLoader that does not see the method.
Common situations: Distributing serialized proxies across JVMs (e.g. via Spring HTTP Invoker, RMI, or a cache), redeploying with a refactored aspect, hot-swapping jars without re-serializing, or ClassLoader isolation between the serializer and deserializer.
Related errors
- Failed to find advice method on deserialization
- Advice method [ ] requires arguments to be bound by name…
- Advice must be declared inside an aspect type: Offending…
- An advice method can never be a constructor
- is not a valid AspectJ annotation
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/bff89e43a6d16c60.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java:702
protected @Nullable JoinPointMatch getJoinPointMatch(ProxyMethodInvocation pmi) {
String expression = this.pointcut.getExpression();
return (expression != null ? (JoinPointMatch) pmi.getUserAttribute(expression) : null);
}
@Override
public String toString() {
return getClass().getName() + ": advice method [" + this.aspectJAdviceMethod + "]; " +
"aspect name '" + this.aspectName + "'";
}
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
inputStream.defaultReadObject();
try {
this.aspectJAdviceMethod = this.declaringClass.getMethod(this.methodName, this.parameterTypes);
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException("Failed to find advice method on deserialization", ex);
}
}
/**
* MethodMatcher that excludes the specified advice method.
* @see AbstractAspectJAdvice#buildSafePointcut()
*/
private static class AdviceExcludingMethodMatcher extends StaticMethodMatcher {
private final Method adviceMethod;
public AdviceExcludingMethodMatcher(Method adviceMethod) {
this.adviceMethod = adviceMethod;
}
@Override
public boolean matches(Method method, Class<?> targetClass) {View on GitHub (pinned to 69bf83ad71)