{"id":"9478f401ecb676db","repo":"spring-projects/spring-framework","slug":"failed-to-find-advice-method-on-deserialization-9478f4","errorCode":null,"errorMessage":"Failed to find advice method on deserialization","messagePattern":"Failed to find advice method on deserialization","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java","lineNumber":246,"sourceCode":"\t\t\t\t\tthis.isBeforeAdvice = true;\n\t\t\t\t\tthis.isAfterAdvice = false;\n\t\t\t\t}\n\t\t\t\tcase AtAfter, AtAfterReturning, AtAfterThrowing -> {\n\t\t\t\t\tthis.isBeforeAdvice = false;\n\t\t\t\t\tthis.isAfterAdvice = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\n\tprivate void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {\n\t\tinputStream.defaultReadObject();\n\t\ttry {\n\t\t\tthis.aspectJAdviceMethod = this.declaringClass.getMethod(this.methodName, this.parameterTypes);\n\t\t}\n\t\tcatch (NoSuchMethodException ex) {\n\t\t\tthrow new IllegalStateException(\"Failed to find advice method on deserialization\", ex);\n\t\t}\n\t}\n\n\t@Override\n\tpublic String toString() {\n\t\treturn \"InstantiationModelAwarePointcutAdvisor: expression [\" + getDeclaredPointcut().getExpression() +\n\t\t\t\t\"]; advice method [\" + this.aspectJAdviceMethod + \"]; perClauseKind=\" +\n\t\t\t\tthis.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();\n\t}\n\n\n\t/**\n\t * Pointcut implementation that changes its behavior when the advice is instantiated.\n\t * Note that this is a <i>dynamic</i> pointcut; otherwise it might be optimized out\n\t * if it does not at first match statically.\n\t */\n\tprivate static final class PerTargetInstantiationModelPointcut extends DynamicMethodMatcherPointcut {\n","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java#L228-L264","documentation":"Thrown by InstantiationModelAwarePointcutAdvisorImpl.readObject() during Java deserialization when the advice method (stored by name, declaring class, and parameter types) cannot be re-resolved via Class.getMethod. This happens when the aspect class on the deserializing JVM no longer has a method with the exact same name and parameter signature — e.g. the aspect was refactored between serialization and deserialization.","triggerScenarios":"Deserializing a serialized AOP proxy (or an advisor chain containing an InstantiationModelAwarePointcutAdvisorImpl) on a JVM/classpath where the aspect class's advice method was renamed, removed, or had its parameter list changed.","commonSituations":"Distributing a serialized Spring AOP proxy across services with different versions of the aspect class. Hot-reloading or upgrading the application between serializing and deserializing a proxy. Refactoring advice method signatures.","solutions":["Ensure the aspect class version on the deserializing side has the exact same advice method name and parameter types as when the proxy was serialized.","Avoid serializing Spring AOP proxies across version boundaries; reconstruct the proxy locally instead.","If a method was legitimately renamed, re-serialize the proxy with the updated class on the producing side."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before deserializing, verify the advice method still exists.\nimport java.lang.reflect.Method;\n\nboolean adviceMethodExists(Class<?> aspectClass, String methodName, Class<?>[] paramTypes) {\n  try { aspectClass.getMethod(methodName, paramTypes); return true; }\n  catch (NoSuchMethodException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  Object proxy = objectInputStream.readObject();\n} catch (IllegalStateException ex) {\n  if (ex.getMessage().equals(\"Failed to find advice method on deserialization\")) {\n    log.error(\"Aspect advice method renamed/removed since serialization\", ex);\n    // rebuild proxy locally instead of deserializing\n  } else throw ex;\n}","preventionTips":["Avoid serializing Spring AOP proxies across versions; rebuild them in-process.","Lock the aspect class version on both sides of a serialized-proxy boundary.","Treat advice method signatures as a serialization contract; do not refactor them incompatibly."],"tags":["spring-aop","aspectj","serialization","deserialization","versioning"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}