quarkusio/quarkus · error · DefinitionException

An interceptor method cannot be marked @Produces or @Dispose

Error message

An interceptor method cannot be marked @Produces or @Disposes - 

What it means

Per the CDI spec, a method of an interceptor class must not be annotated @Produces or @Disposes; interceptors are not beans that can produce or dispose. ArC throws a DefinitionException at build time while scanning interceptor class methods.

Source

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

        AnnotationStore store = beanDeployment.getAnnotationStore();
        List<MethodInfo> aroundInvokes = new ArrayList<>();
        List<MethodInfo> aroundConstructs = new ArrayList<>();
        List<MethodInfo> postConstructs = new ArrayList<>();
        List<MethodInfo> preDestroys = new ArrayList<>();

        List<MethodInfo> allMethods = new ArrayList<>();
        ClassInfo aClass = target.asClass();
        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);
                    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove @Produces/@Disposes from the interceptor method
  2. Move the producer/disposer logic into a separate non-interceptor bean class
  3. Make the method static if it is a pure utility (static methods are skipped by the check)

Example fix

// before
@Interceptor
public class LogInterceptor {
    @Produces
    String make() { return "x"; }
}
// after
@Interceptor
public class LogInterceptor {
    @AroundInvoke
    Object log(InvocationContext ctx) throws Exception { return ctx.proceed(); }
}
Defensive patterns

Strategy: validation

Validate before calling

for (Method m : MyInterceptor.class.getDeclaredMethods()) {
    if (java.lang.reflect.java.lang.reflect.Modifier.isStatic(m.getModifiers())) continue;
    if (m.isAnnotationPresent(Produces.class) || java.util.Arrays.stream(m.getParameterAnnotations())
        .flatMap(java.util.Arrays::stream).anyMatch(a -> a.annotationType().getSimpleName().equals("Disposes"))) {
        throw new IllegalStateException("@Produces/@Disposes in interceptor: " + m);
    }
}

Prevention

When it happens

Trigger: Declaring @Produces or @Disposes on any non-static method of a class registered as an interceptor (has @Interceptor / @AroundInvoke etc.); detected in the InterceptorInfo constructor.

Common situations: Putting producer/disposer utility methods inside an interceptor class; copy-pasting methods between a bean class and an interceptor class.

Related errors


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