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

  1. Avoid serializing prototype-mode ProxyFactoryBean instances; re-fetch them from the context after deserialization.
  2. Switch the advice bean to singleton scope if serialization is unavoidable (placeholders are only used for prototype advice).
  3. 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

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


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/c305c6eeaf723c22.json. Report an issue: GitHub.