spring-projects/spring-framework · error · IllegalStateException
No BeanFactory available anymore (probably due to serializat
Error message
No BeanFactory available anymore (probably due to serialization) - cannot resolve prototype advisor '{ppa.getBeanName()}' What it means
freshAdvisorChain() replaces PrototypePlaceholderAdvisor entries (created for prototype-scope advice beans) with freshly resolved instances. If beanFactory is null at that point - which happens after Java serialization because the field is transient - the lookup cannot proceed and IllegalStateException is thrown. The message names the bean that could not be resolved.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java:468
}
/**
* Return an independent advisor chain.
* We need to do this every time a new prototype instance is returned,
* to return distinct instances of prototype Advisors and Advices.
*/
private List<Advisor> freshAdvisorChain() {
Advisor[] advisors = getAdvisors();
List<Advisor> freshAdvisors = new ArrayList<>(advisors.length);
for (Advisor advisor : advisors) {
if (advisor instanceof PrototypePlaceholderAdvisor ppa) {
if (logger.isDebugEnabled()) {
logger.debug("Refreshing bean named '" + ppa.getBeanName() + "'");
}
// Replace the placeholder with a fresh prototype instance resulting from a getBean lookup
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to " +
"serialization) - cannot resolve prototype advisor '" + ppa.getBeanName() + "'");
}
Object bean = this.beanFactory.getBean(ppa.getBeanName());
Advisor refreshedAdvisor = namedBeanToAdvisor(bean);
freshAdvisors.add(refreshedAdvisor);
}
else {
// Add the shared instance.
freshAdvisors.add(advisor);
}
}
return freshAdvisors;
}
/**
* Add all global interceptors and pointcuts.
*/
private void addGlobalAdvisors(ListableBeanFactory beanFactory, String prefix) {View on GitHub (pinned to e8729d0438)
Solutions
- Avoid serializing prototype-mode ProxyFactoryBean instances; re-fetch them from the context after deserialization.
- Switch the advice bean to singleton scope if serialization is unavoidable (placeholders are only used for prototype advice).
- Hold only the proxy in serialized state and refresh the FactoryBean from the ApplicationContext on the other side.
Example fix
// before <bean class="...ProxyFactoryBean" scope="prototype"> <property name="interceptorNames" value="myPrototypeAdvice"/> </bean> // serialized across nodes // after: make the advice singleton so no placeholder is needed <bean id="myPrototypeAdvice" class="..." scope="singleton"/>
Defensive patterns
Strategy: validation
Validate before calling
// Guard against using a serialized prototype ProxyFactoryBean
if (pfb.getBeanFactory() == null && !pfb.isSingleton()) {
throw new IllegalStateException("Refusing prototype proxy creation: BeanFactory missing (serialized?).");
} Prevention
- Do not serialize prototype ProxyFactoryBean instances.
- Make advice beans singleton scope if serialization is unavoidable.
- Re-resolve prototype proxies from the context after deserialization.
When it happens
Trigger: Serializing a ProxyFactoryBean whose prototype-scope advisor was deferred as a placeholder, then asking for a new prototype proxy instance (singleton=false) on the deserialized object; calling newPrototypeInstance() after the BeanFactory was cleared.
Common situations: Prototype ProxyFactoryBean stored in a session/distributed cache; remote session replication; mixing prototype advice with serialized proxies.
Related errors
- No BeanFactory available anymore (probably due to serializat
- No BeanFactory available anymore (probably due to serializat
- Cannot determine target class for proxy
- Target required after globals
- Can only use global advisors or interceptors with a Listable
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/c305c6eeaf723c22.json.
Report an issue: GitHub.