{"id":"6fa4d2edc5b21c49","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 {Arrays.toString(interceptorNames)}","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/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java#L393-L429","documentation":"initializeAdvisorChain() needs a BeanFactory to materialize the interceptor/advisor beans named in interceptorNames. When beanFactory is null (it is transient and lost on Java serialization), resolving those names is impossible, so Spring throws IllegalStateException. The message explicitly blames serialization because that is the documented reason the field becomes null after deserialization.","triggerScenarios":"Serializing a ProxyFactoryBean (or its proxy) and then triggering re-initialization of the advice chain on the deserialized instance; programmatically calling adviceChanged/setInterceptorNames after the bean was deserialized.","commonSituations":"Storing a Spring AOP proxy or the FactoryBean in an HTTP session or distributed cache that serializes it; remote invocation scenarios; calling getObject() on a deserialized ProxyFactoryBean whose interceptorNames still need resolving.","solutions":["Do not serialize the ProxyFactoryBean itself; serialize only the proxy and rely on Spring to rebuild the factory on the other side.","Re-obtain the proxy from the ApplicationContext after deserialization rather than reusing a deserialized copy.","If you must carry state across, mark the proxy as transient and refresh it from the context post-serialization."],"exampleFix":"// before\nsession.setAttribute(\"proxy\", proxyFactoryBean); // serializes FactoryBean\n\n// after: store only the bean name, look it up after\nsession.setAttribute(\"proxyBeanName\", \"myService\");\nMyService proxy = ctx.getBean(\"myService\", MyService.class);","handlingStrategy":"validation","validationCode":"// Do not serialize ProxyFactoryBean; before using one post-serialization, reattach it\nProxyFactoryBean pfb = ...;\nif (pfb.getBeanFactory() == null && pfb.getInterceptorNames() != null) {\n    throw new IllegalStateException(\"ProxyFactoryBean lost its BeanFactory via serialization; re-resolve from context.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never put a ProxyFactoryBean in an HTTP session or distributed cache.","Serialize only the proxy or a bean name; rebuild the factory from the ApplicationContext.","Mark proxies/factory beans transient and re-resolve after deserialization."],"tags":["aop","serialization","proxy-factory-bean","bean-factory"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}