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

  1. 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.
  2. Switch the prototype-scoped advice to a singleton so no placeholder is used.
  3. 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

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


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/debd956669cfdd0f. Report an issue: GitHub.