{"record":{"id":"08cefb965f684726","repo":"quarkusio/quarkus","slug":"multiple-aroundinvoke-interceptor-methods-declare-08cefb","errorCode":null,"errorMessage":"Multiple @AroundInvoke interceptor methods declared on class: ","messagePattern":"Multiple @AroundInvoke interceptor methods declared on class: ","errorType":"validation","errorClass":"DefinitionException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorInfo.java","lineNumber":118,"sourceCode":"        while (aClass != null) {\n            // Only one interceptor method of a given type may be declared on a given class\n            int aroundInvokesFound = 0, aroundConstructsFound = 0, postConstructsFound = 0, preDestroysFound = 0;\n\n            for (MethodInfo method : aClass.methods()) {\n                if (Modifier.isStatic(method.flags())) {\n                    continue;\n                }\n                if (store.hasAnnotation(method, DotNames.PRODUCES) || store.hasAnnotation(method, DotNames.DISPOSES)) {\n                    // according to spec, finding @Produces or @Disposes on a method is a DefinitionException\n                    throw new DefinitionException(\n                            \"An interceptor method cannot be marked @Produces or @Disposes - \" + method + \" in class: \"\n                                    + aClass);\n                }\n                if (store.hasAnnotation(method, DotNames.AROUND_INVOKE)) {\n                    addInterceptorMethod(allMethods, aroundInvokes, method, InterceptionType.AROUND_INVOKE,\n                            InterceptorPlacement.INTERCEPTOR_CLASS);\n                    if (++aroundInvokesFound > 1) {\n                        throw new DefinitionException(\n                                \"Multiple @AroundInvoke interceptor methods declared on class: \" + aClass);\n                    }\n                }\n                if (store.hasAnnotation(method, DotNames.AROUND_CONSTRUCT)) {\n                    addInterceptorMethod(allMethods, aroundConstructs, method, InterceptionType.AROUND_CONSTRUCT,\n                            InterceptorPlacement.INTERCEPTOR_CLASS);\n                    if (++aroundConstructsFound > 1) {\n                        throw new DefinitionException(\n                                \"Multiple @AroundConstruct interceptor methods declared on class: \" + aClass);\n                    }\n                }\n                if (store.hasAnnotation(method, DotNames.POST_CONSTRUCT)) {\n                    addInterceptorMethod(allMethods, postConstructs, method, InterceptionType.POST_CONSTRUCT,\n                            InterceptorPlacement.INTERCEPTOR_CLASS);\n                    if (++postConstructsFound > 1) {\n                        throw new DefinitionException(\n                                \"Multiple @PostConstruct interceptor methods declared on class: \" + aClass);\n                    }","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorInfo.java#L100-L136","documentation":"ArC (Quarkus's CDI container) throws this DefinitionException at build time when an interceptor class (or any class in its hierarchy, per class in the hierarchy walk) declares more than one non-static method annotated with @AroundInvoke. The CDI specification allows at most one around-invoke interceptor method per interceptor class. Since this is a deployment-time exception, the application fails to start.","triggerScenarios":"Two or more non-static methods in the same interceptor class (or the same superclass level) are annotated @AroundInvoke. The counter resets per class in the hierarchy, so one method in a superclass and one in a subclass is allowed, but two in the same class are not.","commonSituations":"Refactoring merges two interceptor concerns into one class and both keep their @AroundInvoke methods; copying an interceptor method when subclassing an interceptor; IDE auto-generating a second interceptor method.","solutions":["Keep only one @AroundInvoke method per interceptor class; merge the logic of the others into it (delegate to helper methods without the annotation).","Remove the @AroundInvoke annotation from the redundant method, leaving it as a plain helper invoked from the remaining interceptor method.","Split the interceptor into two interceptor classes with separate bindings if the concerns are truly independent."],"exampleFix":"// before\nclass LoggingInterceptor {\n    @AroundInvoke Object log1(InvocationContext ctx) throws Exception { return ctx.proceed(); }\n    @AroundInvoke Object log2(InvocationContext ctx) throws Exception { return ctx.proceed(); }\n}\n// after\nclass LoggingInterceptor {\n    @AroundInvoke Object log(InvocationContext ctx) throws Exception { return ctx.proceed(); }\n}","handlingStrategy":"validation","validationCode":"// Build-time check: scan interceptor class methods before deployment\nlong around = java.util.Arrays.stream(LoggingInterceptor.class.getDeclaredMethods())\n    .filter(m -> m.isAnnotationPresent(jakarta.interceptor.AroundInvoke.class))\n    .count();\nif (around > 1) throw new IllegalStateException(\"Only one @AroundInvoke allowed per interceptor class\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep at most one @AroundInvoke method per interceptor class; use private helpers for extra logic","Search the class (and each hierarchy level) for duplicated lifecycle/around annotations before building","Remember the rule applies per class in the hierarchy, not per interceptor"],"tags":["cdi","quarkus","arc","interceptor","build-time"],"backgroundTag":"multiple-interceptor-methods","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}