{"record":{"id":"ffe638bf6c399ca7","repo":"spring-projects/spring-framework","slug":"no-beanfactory-available-anymore-probably-due-to","errorCode":null,"errorMessage":"No BeanFactory available anymore (probably due to serialization) - cannot resolve interceptor names {}","messagePattern":"No BeanFactory available anymore \\(probably due to serialization\\) - cannot resolve interceptor names (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java","lineNumber":411,"sourceCode":"\t\t}\n\t\t// Treat it as a target bean if we can't tell.\n\t\tif (logger.isDebugEnabled()) {\n\t\t\tlogger.debug(\"Could not determine type of bean with name '\" + beanName +\n\t\t\t\t\t\"' - assuming it is neither an Advisor nor an Advice\");\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Create the advisor (interceptor) chain. Advisors that are sourced\n\t * from a BeanFactory will be refreshed each time a new prototype instance\n\t * is added. Interceptors added programmatically through the factory API\n\t * are unaffected by such changes.\n\t */\n\tprivate synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {\n\t\tif (!this.advisorChainInitialized && !ObjectUtils.isEmpty(this.interceptorNames)) {\n\t\t\tif (this.beanFactory == null) {\n\t\t\t\tthrow new IllegalStateException(\"No BeanFactory available anymore (probably due to serialization) \" +\n\t\t\t\t\t\t\"- cannot resolve interceptor names \" + Arrays.toString(this.interceptorNames));\n\t\t\t}\n\n\t\t\t// Globals can't be last unless we specified a targetSource using the property...\n\t\t\tif (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&\n\t\t\t\t\tthis.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {\n\t\t\t\tthrow new AopConfigException(\"Target required after globals\");\n\t\t\t}\n\n\t\t\t// Materialize interceptor chain from bean names.\n\t\t\tfor (String name : this.interceptorNames) {\n\t\t\t\tif (name.endsWith(GLOBAL_SUFFIX)) {\n\t\t\t\t\tif (!(this.beanFactory instanceof ListableBeanFactory lbf)) {\n\t\t\t\t\t\tthrow new AopConfigException(\n\t\t\t\t\t\t\t\t\"Can only use global advisors or interceptors with a ListableBeanFactory\");\n\t\t\t\t\t}\n\t\t\t\t\taddGlobalAdvisors(lbf, name.substring(0, name.length() - GLOBAL_SUFFIX.length()));\n\t\t\t\t}","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java#L393-L429","documentation":"Thrown as IllegalStateException by ProxyFactoryBean.initializeAdvisorChain when interceptorNames are set but this.beanFactory == null. The beanFactory field is transient, so after deserialization it is null and the factory can no longer resolve interceptor bean names. This signals that a serialized ProxyFactoryBean is being used in a context that lost its BeanFactory.","triggerScenarios":"Serializing a singleton proxy produced by ProxyFactoryBean, deserializing it elsewhere, then triggering re-initialization of the advisor chain (e.g. prototype mode, adviceChanged, or any path that re-enters initializeAdvisorChain with the transient beanFactory now null).","commonSituations":"Distributed session caches (Redis/Hazelcast with Java serialization) holding a Spring AOP proxy bean; HTTP session replication of proxied beans; passing proxied beans through RMI/JMS; serializing application context state for restart.","solutions":["Do not serialize the ProxyFactoryBean or its proxy across JVMs; instead re-resolve the bean from the BeanFactory after deserialization.","Mark such beans as non-serializable and store an identifier, then look them up on the other side.","For sessions, store a stable key and call applicationContext.getBean(name) after deserialization rather than the proxy itself.","If you must serialize proxies, use a JDK interface proxy with serializable advisors and avoid interceptorNames-based configuration (set advisors directly so no BeanFactory is needed at deserialize time)."],"exampleFix":"// before\nsession.setAttribute(\"service\", aopProxyBean); // serialized later\n\n// after\nsession.setAttribute(\"serviceBeanName\", \"service\");\n// on read:\nMyService svc = appCtx.getBean((String) session.getAttribute(\"serviceBeanName\"), MyService.class);","handlingStrategy":"fallback","validationCode":"// Before serializing, store a name and look up on the other side\nif (bean instanceof Advised) {\n  // store an identifier, not the proxy\n  store(\"svcName\", \"myService\");\n}","typeGuard":"static boolean isProxyFactoryBeanDerived(Object o) { return (o instanceof Advised) && Proxy.isProxyClass(o.getClass()); }","tryCatchPattern":"try { advisors = pfb.getAdvisors(); }\ncatch (IllegalStateException e) {\n  if (e.getMessage().contains(\"serialization\")) { /* re-resolve from BeanFactory by name */ }\n  throw e;\n}","preventionTips":["Never put AOP proxies in distributed sessions/caches; store bean names instead.","Inline advisors via addAdvisor rather than interceptorNames if serialization is unavoidable.","For session beans, mark proxies transient and rebuild from the ApplicationContext."],"tags":["spring-aop","proxyfactorybean","serialization","configuration"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}