quarkusio/quarkus · error · DefinitionException
Abstract decorator ${decoratorClass.name()} declares abstrac
Error message
Abstract decorator ${decoratorClass.name()} declares abstract method(s) not present on decorated interface(s):
${badAbstractMethods} What it means
If a decorator is declared abstract, every abstract method it declares must exist on the interfaces it decorates. Arc builds the list of abstract methods not present on any decorated interface and rejects deployment with this DefinitionException.
Source
Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Decorators.java:149
for (Type superclassType : ts.typeWithSuperTypes(Types.getProviderType(decoratorClass), true)) {
// 3. verify that it is also present on at least one decorated type
for (JandexTypeSystem.MethodKey method : ts.methods(superclassType, MethodInfo::isAbstract)) {
if (!abstractMethodsOnDecoratedTypes.contains(method)) {
badAbstractMethods.add(method);
}
}
}
if (!badAbstractMethods.isEmpty()) {
StringBuilder message = new StringBuilder("Abstract decorator ")
.append(decoratorClass.name())
.append(" declares abstract method(s) not present on decorated interface(s):\n");
for (JandexTypeSystem.MethodKey method : badAbstractMethods) {
message.append("\t- ");
method.appendTo(message);
message.append("\n");
}
throw new DefinitionException(message.toString());
}
}
checkDecoratorFieldsAndMethods(decoratorClass, beanDeployment);
return new DecoratorInfo(decoratorClass, beanDeployment, delegateInjectionPoint,
decoratedTypes, injections, priority);
}
private static void checkDecoratorFieldsAndMethods(ClassInfo decoratorClass, BeanDeployment beanDeployment) {
ClassInfo aClass = decoratorClass;
while (aClass != null) {
for (MethodInfo method : aClass.methods()) {
if (beanDeployment.hasAnnotation(method, DotNames.PRODUCES)) {
throw new DefinitionException("Decorator declares a producer method: " + decoratorClass);
}
// the following 3 checks rely on the annotation store returning parameter annotations for methods
if (beanDeployment.hasAnnotation(method, DotNames.DISPOSES)) {View on GitHub (pinned to e1c734241f)
Solutions
- Add the missing method (with matching signature) to the appropriate decorated interface.
- Make the method concrete in the abstract decorator (implement it).
- Remove the stray abstract method from the decorator.
- Synchronize decorator signatures with the current interface after refactoring.
Example fix
// before
@Decorator
public abstract class Base implements Greeter {
abstract void extra(); // not on Greeter
}
// after
@Decorator
public abstract class Base implements Greeter {
void extra() { /* concrete */ }
} Defensive patterns
Strategy: validation
Validate before calling
if (Modifier.isAbstract(decoratorClass.getModifiers())) {
for (Method m : decoratorClass.getDeclaredMethods())
if (Modifier.isAbstract(m.getModifiers())) {
boolean onInterface = Stream.of(decoratorClass.getInterfaces())
.flatMap(i -> Stream.of(i.getMethods()))
.anyMatch(im -> im.getName().equals(m.getName()) && Arrays.equals(im.getParameterTypes(), m.getParameterTypes()));
if (!onInterface) throw new IllegalStateException("Abstract method not on decorated interface: " + m);
}
} Prevention
- Avoid abstract decorators unless necessary; prefer concrete decorators.
- After changing an interface, recompile and check all abstract decorators.
- Keep decorator method signatures generated from the interface (IDE implement-methods).
When it happens
Trigger: Abstract @Decorator class declares an abstract method that none of its decorated interfaces define; usually after removing/renaming a method on the interface or adding an extra abstract method to the decorator.
Common situations: Interface refactored to remove a method while the abstract decorator still declares it; decorator implements multiple interfaces and the abstract method belongs to none; typo in method signature.
Related errors
- Decorated interface ${decoratedType} not found in the index
- The decorator ${decoratorClass} has no decorated type
- The delegate type ${delegateInjectionPoint.getRequiredType()
- Unsupported injection point target: <injectionPoint>
- Method ${method} of class ${beanClass} is not a producer met
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/155018f061a52f40.
Report an issue: GitHub.