spring-projects/spring-framework · error · UnknownAdviceTypeException

Advice object [{advisor.getAdvice()}] is neither a supported

Error message

Advice object [{advisor.getAdvice()}] is neither a supported subinterface of [org.aopalliance.aop.Advice] nor an [org.springframework.aop.Advisor]

What it means

getInterceptors(Advisor) tries to produce MethodInterceptors for an Advisor's advice: directly if it is a MethodInterceptor, or via a supporting AdvisorAdapter. If neither applies, the list stays empty and UnknownAdviceTypeException is thrown, naming the advice. This is the runtime analog of error 91 - it fires at invocation-chain assembly time.

Source

Thrown at spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java:93

			}
		}
		throw new UnknownAdviceTypeException(advice);
	}

	@Override
	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<>(3);
		Advice advice = advisor.getAdvice();
		if (advice instanceof MethodInterceptor methodInterceptor) {
			interceptors.add(methodInterceptor);
		}
		for (AdvisorAdapter adapter : this.adapters) {
			if (adapter.supportsAdvice(advice)) {
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
		if (interceptors.isEmpty()) {
			throw new UnknownAdviceTypeException(advisor.getAdvice());
		}
		return interceptors.toArray(EMPTY_METHOD_INTERCEPTOR_ARRAY);
	}

	@Override
	public void registerAdvisorAdapter(AdvisorAdapter adapter) {
		this.adapters.add(adapter);
	}

}

View on GitHub (pinned to e8729d0438)

Solutions

  1. Ensure an AdvisorAdapter is registered (DefaultAdvisorAdapterRegistry.registerAdvisorAdapter) for the advice type before the proxy is built.
  2. Make the Advisor's advice implement MethodInterceptor directly so no adapter is needed.
  3. Use the same AdvisorAdapterRegistry instance across the ProxyFactory configuration (setAdvisorAdapterRegistry).

Example fix

// before
class CustomAdvisor implements Advisor {
  public Advice getAdvice() { return new CustomAdvice(); } // unknown type
}

// after
((DefaultAdvisorAdapterRegistry) registry).registerAdvisorAdapter(new CustomAdviceAdapter());
// where CustomAdviceAdapter implements AdvisorAdapter and returns a MethodInterceptor
Defensive patterns

Strategy: type-guard

Validate before calling

Advisor advisor = ...;
Advice a = advisor.getAdvice();
boolean ok = a instanceof org.aopalliance.intercept.MethodInterceptor
    || java.util.Arrays.stream(adapters).anyMatch(ad -> ad.supportsAdvice(a));
if (!ok) throw new IllegalStateException("Advisor's advice has no adapter: " + a.getClass());

Type guard

public static boolean hasInterceptorOrAdapter(Advice a, List<AdvisorAdapter> adapters) {
    if (a instanceof org.aopalliance.intercept.MethodInterceptor) return true;
    return adapters.stream().anyMatch(ad -> ad.supportsAdvice(a));
}

Try / catch

try {
    return registry.getInterceptors(advisor);
} catch (UnknownAdviceTypeException ex) {
    throw new BeanInitializationException("No adapter for advisor advice " + advisor.getAdvice().getClass(), ex);
}

Prevention

When it happens

Trigger: An Advisor returns an Advice that is not a MethodInterceptor and not supported by any registered adapter, encountered when the proxy's interceptor chain is built (e.g. during getProxy() or first invocation).

Common situations: Custom Advice/Advisor introduced without its adapter; partial config where an adapter was registered in one registry instance but a different default registry is used at runtime; classpath changes removing the adapter bean.

Related errors


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