quarkusio/quarkus · error · DefinitionException

Multiple @AroundInvoke interceptor methods declared on class

Error message

Multiple @AroundInvoke interceptor methods declared on class: 

What it means

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.

Source

Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptorInfo.java:118

        while (aClass != null) {
            // Only one interceptor method of a given type may be declared on a given class
            int aroundInvokesFound = 0, aroundConstructsFound = 0, postConstructsFound = 0, preDestroysFound = 0;

            for (MethodInfo method : aClass.methods()) {
                if (Modifier.isStatic(method.flags())) {
                    continue;
                }
                if (store.hasAnnotation(method, DotNames.PRODUCES) || store.hasAnnotation(method, DotNames.DISPOSES)) {
                    // according to spec, finding @Produces or @Disposes on a method is a DefinitionException
                    throw new DefinitionException(
                            "An interceptor method cannot be marked @Produces or @Disposes - " + method + " in class: "
                                    + aClass);
                }
                if (store.hasAnnotation(method, DotNames.AROUND_INVOKE)) {
                    addInterceptorMethod(allMethods, aroundInvokes, method, InterceptionType.AROUND_INVOKE,
                            InterceptorPlacement.INTERCEPTOR_CLASS);
                    if (++aroundInvokesFound > 1) {
                        throw new DefinitionException(
                                "Multiple @AroundInvoke interceptor methods declared on class: " + aClass);
                    }
                }
                if (store.hasAnnotation(method, DotNames.AROUND_CONSTRUCT)) {
                    addInterceptorMethod(allMethods, aroundConstructs, method, InterceptionType.AROUND_CONSTRUCT,
                            InterceptorPlacement.INTERCEPTOR_CLASS);
                    if (++aroundConstructsFound > 1) {
                        throw new DefinitionException(
                                "Multiple @AroundConstruct interceptor methods declared on class: " + aClass);
                    }
                }
                if (store.hasAnnotation(method, DotNames.POST_CONSTRUCT)) {
                    addInterceptorMethod(allMethods, postConstructs, method, InterceptionType.POST_CONSTRUCT,
                            InterceptorPlacement.INTERCEPTOR_CLASS);
                    if (++postConstructsFound > 1) {
                        throw new DefinitionException(
                                "Multiple @PostConstruct interceptor methods declared on class: " + aClass);
                    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Keep only one @AroundInvoke method per interceptor class; merge the logic of the others into it (delegate to helper methods without the annotation).
  2. Remove the @AroundInvoke annotation from the redundant method, leaving it as a plain helper invoked from the remaining interceptor method.
  3. Split the interceptor into two interceptor classes with separate bindings if the concerns are truly independent.

Example fix

// before
class LoggingInterceptor {
    @AroundInvoke Object log1(InvocationContext ctx) throws Exception { return ctx.proceed(); }
    @AroundInvoke Object log2(InvocationContext ctx) throws Exception { return ctx.proceed(); }
}
// after
class LoggingInterceptor {
    @AroundInvoke Object log(InvocationContext ctx) throws Exception { return ctx.proceed(); }
}
Defensive patterns

Strategy: validation

Validate before calling

// Build-time check: scan interceptor class methods before deployment
long around = java.util.Arrays.stream(LoggingInterceptor.class.getDeclaredMethods())
    .filter(m -> m.isAnnotationPresent(jakarta.interceptor.AroundInvoke.class))
    .count();
if (around > 1) throw new IllegalStateException("Only one @AroundInvoke allowed per interceptor class");

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/08cefb965f684726. Report an issue: GitHub.