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

  1. Do not call getAdvice() on advisors of a prototype ProxyFactoryBean; trigger proxy creation first so placeholders are resolved into real advisors.
  2. Filter out PrototypePlaceholderAdvisor instances (they are private, so check via instanceof Advisor and getClass().getName()) before introspection.
  3. 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

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


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