spring-projects/spring-framework · error · UnsupportedOperationException
Cannot invoke methods: {message}
Error message
Cannot invoke methods: {message} What it means
PrototypePlaceholderAdvisor.getAdvice() is not supported - the placeholder is only an internal marker holding a bean name until the real prototype advisor can be resolved. Calling getAdvice() (or any reflective invocation that needs the advice) triggers UnsupportedOperationException with this message.
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 e8729d0438)
Solutions
- Do not call getAdvice() on advisors of a prototype ProxyFactoryBean; trigger proxy creation first so placeholders are resolved into real advisors.
- Filter out PrototypePlaceholderAdvisor instances (they are private, so check via instanceof Advisor and getClass().getName()) before introspection.
- Switch the advice bean to singleton scope to eliminate placeholders.
Example fix
// before
for (Advisor a : proxyFactoryBean.getAdvisors()) {
a.getAdvice(); // blows up on placeholder
}
// after
// trigger materialization first, then introspect
Object proxy = proxyFactoryBean.getObject();
Advised advised = (Advised) proxy;
for (Advisor a : advised.getAdvisors()) {
a.getAdvice(); // safe - resolved
} Defensive patterns
Strategy: type-guard
Validate before calling
// Avoid calling getAdvice() on unmaterialized placeholders
for (Advisor a : advised.getAdvisors()) {
if (!a.getClass().getName().contains("PrototypePlaceholderAdvisor")) {
a.getAdvice();
}
} Type guard
public static boolean isResolvedAdvisor(Advisor a) {
return a != null && !a.getClass().getName().contains("PrototypePlaceholderAdvisor");
} Try / catch
try {
return advisor.getAdvice();
} catch (UnsupportedOperationException ex) {
if (ex.getMessage().startsWith("Cannot invoke methods")) {
log.warn("Skipping placeholder advisor: {}", advisor);
return null;
}
throw ex;
} Prevention
- Trigger proxy creation (getObject()) before introspecting advisors so placeholders are resolved.
- Filter PrototypePlaceholderAdvisor instances out of introspection loops.
- Switch prototype advice to singleton scope when introspection is required.
When it happens
Trigger: Reflectively inspecting or invoking a PrototypePlaceholderAdvisor's advice before the placeholder has been replaced during freshAdvisorChain(); programmatically calling getAdvice() on advisors obtained from a prototype-mode ProxyFactoryBean that has not yet materialized its chain.
Common situations: Custom introspection code that iterates getAdvisors() and calls getAdvice() on each; tooling/debuggers touching the placeholder; AOP infrastructure code that does not first refresh the prototype chain.
Related errors
- No BeanFactory available anymore (probably due to serializat
- Unknown advisor type {next.getClass()}; can only include Adv
- Advice object [{adviceObject}] is neither a supported subint
- Illegal MethodMatcher usage
- Cannot use PrototypeAspectInstanceFactory with bean named '{
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/08cac5ec7ec038f7.json.
Report an issue: GitHub.