quarkusio/quarkus · error · DefinitionException

Initializer method must not be annotated @Produces (alternat

Error message

Initializer method must not be annotated @Produces (alternatively, producer method must not be annotated @Inject): 

What it means

ArC throws this DefinitionException when a method annotated @Inject (an initializer/injection method) is also annotated @Produces, or equivalently when a producer method is annotated @Inject. A method cannot simultaneously be an initializer and a producer — the CDI spec forbids the combination and forBean validates initializer methods for this conflict.

Source

Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java:251

                    if (DotNames.OBSERVES.equals(annotation.name())) {
                        throw new DefinitionException(
                                "Bean constructor must not have an @Observes parameter: " + injectConstructor);
                    }
                    if (DotNames.OBSERVES_ASYNC.equals(annotation.name())) {
                        throw new DefinitionException(
                                "Bean constructor must not have an @ObservesAsync parameter: " + injectConstructor);
                    }
                }
            }

            Set<MethodInfo> initializerMethods = injections.stream()
                    .filter(it -> it.isMethod() && !it.isConstructor())
                    .map(Injection::getTarget)
                    .map(AnnotationTarget::asMethod)
                    .collect(Collectors.toSet());
            for (MethodInfo initializerMethod : initializerMethods) {
                if (beanDeployment.hasAnnotation(initializerMethod, DotNames.PRODUCES)) {
                    throw new DefinitionException("Initializer method must not be annotated @Produces "
                            + "(alternatively, producer method must not be annotated @Inject): "
                            + beanTarget.asClass() + "." + initializerMethod.name());
                }
                if (Annotations.hasParameterAnnotation(beanDeployment, initializerMethod, DotNames.DISPOSES)) {
                    throw new DefinitionException("Initializer method must not have a @Disposes parameter "
                            + "(alternatively, disposer method must not be annotated @Inject): "
                            + beanTarget.asClass() + "." + initializerMethod.name());
                }
                if (Annotations.hasParameterAnnotation(beanDeployment, initializerMethod, DotNames.OBSERVES)) {
                    throw new DefinitionException("Initializer method must not have an @Observes parameter "
                            + "(alternatively, observer method must not be annotated @Inject): "
                            + beanTarget.asClass() + "." + initializerMethod.name());
                }
                if (Annotations.hasParameterAnnotation(beanDeployment, initializerMethod, DotNames.OBSERVES_ASYNC)) {
                    throw new DefinitionException("Initializer method must not have an @ObservesAsync parameter "
                            + "(alternatively, async observer method must not be annotated @Inject): "
                            + beanTarget.asClass() + "." + initializerMethod.name());
                }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Decide the method's role: if it produces a bean, remove @Inject and keep @Produces
  2. If it is an initializer (setter injection), remove @Produces and keep @Inject
  3. If field injection suffices, use @Inject on a field and a separate @Produces method for the produced type
  4. Rebuild; validation happens at Quarkus augmentation time

Example fix

// before
@Inject
@Produces
@ApplicationScoped
Service service() { return new Service(); }

// after
@Produces
@ApplicationScoped
Service service() { return new Service(); }
Defensive patterns

Strategy: validation

Validate before calling

void checkMethod(Method m) {
    boolean inject = m.isAnnotationPresent(jakarta.inject.Inject.class);
    boolean produces = m.isAnnotationPresent(jakarta.enterprise.inject.Produces.class);
    if (inject && produces) {
        throw new IllegalStateException("@Inject + @Produces on: " + m);
    }
}

Prevention

When it happens

Trigger: Annotating a method with both @Inject and @Produces in a bean class; detected when ArC checks initializerMethods (non-constructor injection methods) for DotNames.PRODUCES in forBean.

Common situations: Adding @Produces to an existing @Inject setter; IDE quick-fix adding both annotations; misunderstanding that @Inject+@Produces makes a 'producing initializer'; migration between CDI versions where such combinations were accidentally tolerated elsewhere.

Related errors


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