quarkusio/quarkus · error · DefinitionException
Disposer method must not be annotated @Produces (alternative
Error message
Disposer method must not be annotated @Produces (alternatively, producer method must not have a @Disposes parameter):
What it means
Build-time CDI definition error from Injection.forDisposer: the disposer method (one having a @Disposes parameter) is also annotated @Produces, making it simultaneously a producer method and a disposer — an illegal combination. The method is appended to the message text.
Source
Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java:409
// injections are discovered bottom-up to easily skip overriden methods,
// but they need to be performed top-down per the AtInject specification
superInjections.addAll(injections);
injections = superInjections;
}
}
return injections;
}
static Injection forDisposer(MethodInfo disposerMethod, ClassInfo beanClass, BeanDeployment beanDeployment,
InjectionPointModifier transformer) {
if (beanDeployment.hasAnnotation(disposerMethod, DotNames.INJECT)) {
throw new DefinitionException("Disposer method must not be annotated @Inject "
+ "(alternatively, initializer method must not have a @Disposes parameter): "
+ disposerMethod);
}
if (beanDeployment.hasAnnotation(disposerMethod, DotNames.PRODUCES)) {
throw new DefinitionException("Disposer method must not be annotated @Produces "
+ "(alternatively, producer method must not have a @Disposes parameter): "
+ disposerMethod);
}
if (Annotations.hasParameterAnnotation(beanDeployment, disposerMethod, DotNames.OBSERVES)) {
throw new DefinitionException("Disposer method must not have an @Observes parameter "
+ "(alternatively, observer method must not have a @Disposes parameter): "
+ disposerMethod);
}
if (Annotations.hasParameterAnnotation(beanDeployment, disposerMethod, DotNames.OBSERVES_ASYNC)) {
throw new DefinitionException("Disposer method must not have an @ObservesAsync parameter "
+ "(alternatively, async observer method must not have a @Disposes parameter): "
+ disposerMethod);
}
if (Annotations.getParameterAnnotations(beanDeployment, disposerMethod)
.stream()
.filter(it -> DotNames.DISPOSES.equals(it.name()))
.count() > 1) {
throw new DefinitionException("Disposer method must not have more than 1 @Disposes parameter: "View on GitHub (pinned to e1c734241f)
Solutions
- Remove @Produces from the disposer method
- Split into a @Produces method plus a separate disposer method with the @Disposes parameter
- If the method was meant to be a producer, remove the @Disposes parameter
Example fix
// before
@Produces
void handle(@Disposes Widget w) {}
// after
@Produces
Widget produce() { return new Widget(); }
void dispose(@Disposes Widget w) {} Defensive patterns
Strategy: validation
Validate before calling
for (Method m : MyClass.class.getDeclaredMethods()) {
boolean hasDisposes = java.util.Arrays.stream(m.getParameterAnnotations())
.flatMap(java.util.Arrays::stream).anyMatch(a -> a.annotationType().getSimpleName().equals("Disposes"));
if (hasDisposes && m.isAnnotationPresent(Produces.class)) {
throw new IllegalStateException("@Produces disposer: " + m);
}
} Prevention
- A producer and its disposer must be separate methods
- Remove @Produces when adding a @Disposes parameter to a method
When it happens
Trigger: Annotating a method that has a @Disposes parameter with @Produces; detected in Injection.forDisposer at build time.
Common situations: Trying to produce a bean and dispose it in the same method; accidentally leaving @Produces on a method when adding a @Disposes parameter.
Related errors
- An interceptor method cannot be marked @Produces or @Dispose
- No producer method or field declared by the bean class that
- Producer field type is a parameterized type with a type vari
- No disposed parameters found for ${disposerMethod}
- Multiple disposed parameters found for ${disposerMethod}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/af9596f8d3931df0.
Report an issue: GitHub.