spring-projects/spring-framework · warning · UnsupportedOperationException
Cannot invoke methods: {}
Error message
Cannot invoke methods: {} What it means
Thrown as UnsupportedOperationException by ProxyFactoryBean's private PrototypePlaceholderAdvisor.getAdvice(). Placeholders stand in for prototype-scoped advice beans during chain construction and are normally resolved (replaced with a real Advisor) before being used. Calling getAdvice() directly on the placeholder is illegal; it only exists to hold the bean name until refresh.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java:613
*/
private static class PrototypePlaceholderAdvisor implements Advisor, Serializable {
private final String beanName;
private final String message;
public PrototypePlaceholderAdvisor(String beanName) {
this.beanName = beanName;
this.message = "Placeholder for prototype Advisor/Advice with bean name '" + beanName + "'";
}
public String getBeanName() {
return this.beanName;
}
@Override
public Advice getAdvice() {
throw new UnsupportedOperationException("Cannot invoke methods: " + this.message);
}
@Override
public String toString() {
return this.message;
}
}
}
View on GitHub (pinned to 69bf83ad71)
Solutions
- Do not call getAdvice() on advisors returned by a prototype ProxyFactoryBean before the chain is materialized; trigger resolution first by getting a fresh prototype instance.
- Switch the prototype-scoped advice to a singleton so no placeholder is used.
- Use instanceof checks against known advice types and skip placeholders (their toString() carries the bean name).
Example fix
// before
for (Advisor a : factoryBean.getAdvisors()) {
Advice ad = a.getAdvice(); // throws on placeholder
}
// after
for (Advisor a : factoryBean.getAdvisors()) {
if (a.getClass().getSimpleName().contains("Placeholder")) continue;
Advice ad = a.getAdvice();
} Defensive patterns
Strategy: type-guard
Validate before calling
for (Advisor a : pfb.getAdvisors()) {
if (a.getClass().getName().contains("PrototypePlaceholderAdvisor")) continue;
Advice ad = a.getAdvice();
} Type guard
static boolean isPlaceholder(Advisor a) {
return a.getClass().getName().contains("PrototypePlaceholderAdvisor");
} Try / catch
try { advice = a.getAdvice(); }
catch (UnsupportedOperationException e) {
if (e.getMessage().startsWith("Cannot invoke methods")) { /* skip placeholder */ }
throw e;
} Prevention
- Do not introspect getAdvice() on advisors of a prototype ProxyFactoryBean before resolution.
- Prefer singleton advice to avoid placeholders entirely.
- Filter by advisor class name when walking the chain for diagnostics.
When it happens
Trigger: Introspecting getAdvisors() on a ProxyFactoryBean that has prototype advisors in its chain and immediately calling getAdvice() on the returned Advisor before the prototype is materialized — for example, custom code walking the advisor chain of a freshly-built prototype proxy before resolution, or a debug/inspection tool.
Common situations: Diagnostic code that iterates getAdvisors() and calls .getAdvice() to log details; test code asserting on advisor types before the prototype lookup has run; integration with libraries that walk the advised chain.
Related errors
- No BeanFactory available anymore (probably due to serializat
- Cannot remove Advisor: Configuration is frozen.
- Advisor index {} is out of bounds: This configuration only h
- Cannot add advisor: Configuration is frozen.
- Illegal position {} in advisor list with size {}
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/debd956669cfdd0f.
Report an issue: GitHub.