spring-projects/spring-framework · error · UnknownAdviceTypeException

Advice object [{advice}] is neither a supported subinterface

Error message

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

What it means

Inside wrap(), after confirming the object is Advice, Spring checks if it is a MethodInterceptor (wrapped directly) or supported by one of the registered AdvisorAdapters. If none of those match - i.e. an Advice subinterface that Spring does not natively understand - UnknownAdviceTypeException is thrown.

Source

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

	@Override
	public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
		if (adviceObject instanceof Advisor advisor) {
			return advisor;
		}
		if (!(adviceObject instanceof Advice advice)) {
			throw new UnknownAdviceTypeException(adviceObject);
		}
		if (advice instanceof MethodInterceptor) {
			// So well-known it doesn't even need an adapter.
			return new DefaultPointcutAdvisor(advice);
		}
		for (AdvisorAdapter adapter : this.adapters) {
			// Check that it is supported.
			if (adapter.supportsAdvice(advice)) {
				return new DefaultPointcutAdvisor(advice);
			}
		}
		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);

View on GitHub (pinned to e8729d0438)

Solutions

  1. Implement one of the supported advice interfaces (MethodInterceptor is the universal fallback).
  2. Register a custom AdvisorAdapter for your Advice type via AdvisorAdapterRegistry.registerAdvisorAdapter().
  3. Wrap your advice in a custom Advisor that returns a MethodInterceptor from getInterceptors().

Example fix

// before
class MyIntroAdvice implements Advice {} // unsupported subinterface
registry.wrap(new MyIntroAdvice());

// after: implement MethodInterceptor
import org.aopalliance.intercept.MethodInterceptor;
class MyIntroAdvice implements MethodInterceptor {
  public Object invoke(MethodInvocation mi) throws Throwable { return mi.proceed(); }
}
Defensive patterns

Strategy: type-guard

Validate before calling

Object advice = ...;
boolean supported = advice instanceof org.aopalliance.intercept.MethodInterceptor
    || advice instanceof org.springframework.aop.MethodBeforeAdvice
    || advice instanceof org.springframework.aop.AfterReturningAdvice
    || advice instanceof org.springframework.aop.ThrowsAdvice;
if (!supported) throw new IllegalArgumentException("Unsupported advice type: " + advice.getClass());

Type guard

public static boolean isSupportedAdvice(Object o) {
    return o instanceof org.aopalliance.intercept.MethodInterceptor
        || o instanceof org.springframework.aop.MethodBeforeAdvice
        || o instanceof org.springframework.aop.AfterReturningAdvice
        || o instanceof org.springframework.aop.ThrowsAdvice;
}

Try / catch

try {
    return registry.wrap(advice);
} catch (UnknownAdviceTypeException ex) {
    // implement MethodInterceptor or register a custom AdvisorAdapter
    throw ex;
}

Prevention

When it happens

Trigger: An Advice implementation that is neither MethodInterceptor nor one of the three built-in advice types (MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice); a custom Advice interface without a registered AdvisorAdapter.

Common situations: Introducing a new Advice subtype without writing an AdvisorAdapter; version mismatch where a custom adapter that used to be registered is now missing; mixing in non-Spring AOP Alliance advice variants.

Related errors


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