{"id":"f3532d62423c9e0d","repo":"spring-projects/spring-framework","slug":"advice-object-advice-is-neither-a-supported-su","errorCode":null,"errorMessage":"Advice object [{advice}] is neither a supported subinterface of [org.aopalliance.aop.Advice] nor an [org.springframework.aop.Advisor]","messagePattern":"Advice object \\[(.+?)\\] is neither a supported subinterface of \\[org\\.aopalliance\\.aop\\.Advice\\] nor an \\[org\\.springframework\\.aop\\.Advisor\\]","errorType":"exception","errorClass":"UnknownAdviceTypeException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java","lineNumber":77,"sourceCode":"\t@Override\n\tpublic Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {\n\t\tif (adviceObject instanceof Advisor advisor) {\n\t\t\treturn advisor;\n\t\t}\n\t\tif (!(adviceObject instanceof Advice advice)) {\n\t\t\tthrow new UnknownAdviceTypeException(adviceObject);\n\t\t}\n\t\tif (advice instanceof MethodInterceptor) {\n\t\t\t// So well-known it doesn't even need an adapter.\n\t\t\treturn new DefaultPointcutAdvisor(advice);\n\t\t}\n\t\tfor (AdvisorAdapter adapter : this.adapters) {\n\t\t\t// Check that it is supported.\n\t\t\tif (adapter.supportsAdvice(advice)) {\n\t\t\t\treturn new DefaultPointcutAdvisor(advice);\n\t\t\t}\n\t\t}\n\t\tthrow new UnknownAdviceTypeException(advice);\n\t}\n\n\t@Override\n\tpublic MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {\n\t\tList<MethodInterceptor> interceptors = new ArrayList<>(3);\n\t\tAdvice advice = advisor.getAdvice();\n\t\tif (advice instanceof MethodInterceptor methodInterceptor) {\n\t\t\tinterceptors.add(methodInterceptor);\n\t\t}\n\t\tfor (AdvisorAdapter adapter : this.adapters) {\n\t\t\tif (adapter.supportsAdvice(advice)) {\n\t\t\t\tinterceptors.add(adapter.getInterceptor(advisor));\n\t\t\t}\n\t\t}\n\t\tif (interceptors.isEmpty()) {\n\t\t\tthrow new UnknownAdviceTypeException(advisor.getAdvice());\n\t\t}\n\t\treturn interceptors.toArray(EMPTY_METHOD_INTERCEPTOR_ARRAY);","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java#L59-L95","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Implement one of the supported advice interfaces (MethodInterceptor is the universal fallback).","Register a custom AdvisorAdapter for your Advice type via AdvisorAdapterRegistry.registerAdvisorAdapter().","Wrap your advice in a custom Advisor that returns a MethodInterceptor from getInterceptors()."],"exampleFix":"// before\nclass MyIntroAdvice implements Advice {} // unsupported subinterface\nregistry.wrap(new MyIntroAdvice());\n\n// after: implement MethodInterceptor\nimport org.aopalliance.intercept.MethodInterceptor;\nclass MyIntroAdvice implements MethodInterceptor {\n  public Object invoke(MethodInvocation mi) throws Throwable { return mi.proceed(); }\n}","handlingStrategy":"type-guard","validationCode":"Object advice = ...;\nboolean supported = advice instanceof org.aopalliance.intercept.MethodInterceptor\n    || advice instanceof org.springframework.aop.MethodBeforeAdvice\n    || advice instanceof org.springframework.aop.AfterReturningAdvice\n    || advice instanceof org.springframework.aop.ThrowsAdvice;\nif (!supported) throw new IllegalArgumentException(\"Unsupported advice type: \" + advice.getClass());","typeGuard":"public static boolean isSupportedAdvice(Object o) {\n    return o instanceof org.aopalliance.intercept.MethodInterceptor\n        || o instanceof org.springframework.aop.MethodBeforeAdvice\n        || o instanceof org.springframework.aop.AfterReturningAdvice\n        || o instanceof org.springframework.aop.ThrowsAdvice;\n}","tryCatchPattern":"try {\n    return registry.wrap(advice);\n} catch (UnknownAdviceTypeException ex) {\n    // implement MethodInterceptor or register a custom AdvisorAdapter\n    throw ex;\n}","preventionTips":["Implement one of the supported advice interfaces (MethodInterceptor is universal).","Register a custom AdvisorAdapter for bespoke advice types before wrapping.","Add unit tests that call wrap() on each advice bean at context bootstrap."],"tags":["aop","advice","advisor-adapter","type-mismatch"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}