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

  1. Add the missing method (with matching signature) to the appropriate decorated interface.
  2. Make the method concrete in the abstract decorator (implement it).
  3. Remove the stray abstract method from the decorator.
  4. 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

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


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