{"record":{"id":"c13573e421142ec8","repo":"quarkusio/quarkus","slug":"multiple-aroundinvoke-interceptor-methods-declare","errorCode":null,"errorMessage":"Multiple @AroundInvoke interceptor methods declared on class: ${beanClass}","messagePattern":"Multiple @AroundInvoke interceptor methods declared on class: (.+?)","errorType":"exception","errorClass":"DefinitionException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java","lineNumber":784,"sourceCode":"    }\n\n    static List<MethodInfo> getAroundInvokes(ClassInfo beanClass, BeanDeployment deployment) {\n        AnnotationStore store = deployment.getAnnotationStore();\n        List<MethodInfo> methods = new ArrayList<>();\n\n        List<MethodInfo> allMethods = new ArrayList<>();\n        ClassInfo aClass = beanClass;\n        while (aClass != null) {\n            int aroundInvokesFound = 0;\n            for (MethodInfo method : aClass.methods()) {\n                if (Modifier.isStatic(method.flags())) {\n                    continue;\n                }\n                if (store.hasAnnotation(method, DotNames.AROUND_INVOKE)) {\n                    InterceptorInfo.addInterceptorMethod(allMethods, methods, method, InterceptionType.AROUND_INVOKE,\n                            InterceptorPlacement.TARGET_CLASS);\n                    if (++aroundInvokesFound > 1) {\n                        throw new DefinitionException(\n                                \"Multiple @AroundInvoke interceptor methods declared on class: \" + aClass);\n                    }\n                }\n                allMethods.add(method);\n            }\n            DotName superTypeName = aClass.superName();\n            aClass = superTypeName == null || DotNames.OBJECT.equals(superTypeName) ? null\n                    : getClassByName(deployment.getBeanArchiveIndex(), superTypeName);\n        }\n        Collections.reverse(methods);\n        return methods.isEmpty() ? List.of() : List.copyOf(methods);\n    }\n\n    static void analyzeType(Type type, BeanDeployment beanDeployment) {\n        if (type.kind() == Type.Kind.PARAMETERIZED_TYPE) {\n            for (Type argument : type.asParameterizedType().arguments()) {\n                fetchType(argument, beanDeployment);\n            }","sourceCodeStart":766,"sourceCodeEnd":802,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java#L766-L802","documentation":"A CDI interceptor (or intercepted bean class) may declare at most one @AroundInvoke interceptor method, including methods inherited from superclasses. ArC counts matching methods while walking the class hierarchy and throws a DefinitionException when a second one is found.","triggerScenarios":"While building interceptor methods for aClass, a second method annotated @AroundInvoke is encountered (aroundInvokesFound > 1), counting methods declared on the class and all its superclasses.","commonSituations":"A subclass adds its own @AroundInvoke while the superclass already has one; copy-pasting an interceptor method into a class that already defines one; merging code from two interceptor classes into one.","solutions":["Remove one of the @AroundInvoke methods or drop its annotation","Merge the logic of both methods into a single @AroundInvoke method","Move the shared logic into a helper called by one @AroundInvoke method"],"exampleFix":"// before\nclass MyInterceptor {\n  @AroundInvoke Object a(InvocationContext ctx) {...}\n  @AroundInvoke Object b(InvocationContext ctx) {...}\n}\n// after\nclass MyInterceptor {\n  @AroundInvoke Object intercept(InvocationContext ctx) { return a(ctx); }\n  Object a(InvocationContext ctx) {...}\n}","handlingStrategy":"validation","validationCode":"// quick architectural check before building an interceptor\nclass MyInterceptor {\n  long aroundInvokeCount = Stream.of(MyInterceptor.class.getDeclaredMethods(),\n          MyInterceptor.class.getMethods())\n      .flatMap(Stream::of).distinct()\n      .filter(m -> m.isAnnotationPresent(AroundInvoke.class)).count();\n  if (aroundInvokeCount > 1) throw new IllegalStateException(\"Only one @AroundInvoke allowed\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    quarkusBuild.start();\n} catch (DefinitionException e) {\n    if (e.getMessage().contains(\"Multiple @AroundInvoke interceptor methods\")) {\n        logger.errorf(\"Collapse to a single @AroundInvoke: %s\", e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Only one @AroundInvoke per class hierarchy","Search superclasses for existing @AroundInvoke before adding one","Prefer delegating to a private helper method for extra logic"],"tags":["cdi","arc","interceptor","around-invoke"],"backgroundTag":"multiple-around-invoke-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"}