quarkusio/quarkus · error · RuntimeException

Method '${info.name()} of class '${info.declaringClass().nam

Error message

Method '${info.name()} of class '${info.declaringClass().name()}' cannot be static as it is annotated with '@jakarta.ws.rs.ext.Provider'

What it means

checkModifiers in ServerExceptionMapperGenerator rejects static methods annotated as exception mappers. Generated server code invokes mapper methods on a bean instance, so static methods cannot be wired; a RuntimeException fails the build.

Source

Thrown at independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/exceptionmappers/ServerExceptionMapperGenerator.java:645

                    return ReturnType.UNI_RESPONSE;
                }
                if (parameterizedType.arguments().get(0).name().equals(REST_RESPONSE)) {
                    return ReturnType.UNI_REST_RESPONSE;
                }
            }
        }
        throw new RuntimeException("Method '" + targetMethod.name() + " of class '" + targetMethod.declaringClass().name()
                + "' cannot be used as an exception mapper as it does not declare 'Response' or 'Uni<Response>' or as its return type");
    }

    private static void checkModifiers(MethodInfo info) {
        if ((info.flags() & Modifier.PRIVATE) != 0) {
            throw new RuntimeException("Method '" + info.name() + " of class '" + info.declaringClass().name()
                    + "' cannot be private as it is annotated with '@" + SERVER_EXCEPTION_MAPPER
                    + "'");
        }
        if ((info.flags() & Modifier.STATIC) != 0) {
            throw new RuntimeException("Method '" + info.name() + " of class '" + info.declaringClass().name()
                    + "' cannot be static as it is annotated with '@" + SERVER_EXCEPTION_MAPPER
                    + "'");
        }
    }

    private static String getGeneratedClassName(MethodInfo targetMethod, Type handledExceptionType) {
        return targetMethod.declaringClass().name() + "$ExceptionMapper$"
                + HashUtil.sha1(targetMethod.name() + handledExceptionType.name().toString());
    }

    private enum ReturnType {
        RESPONSE,
        REST_RESPONSE,
        UNI_RESPONSE,
        UNI_REST_RESPONSE
    }

    private static class TargetMethodParamsInfo {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove the static modifier from the mapper method
  2. If truly stateless, keep it as a public instance method (CDI can instantiate it)
  3. Remove the mapper annotation if the static method is not a mapper

Example fix

// before
@ServerExceptionMapper
public static Response map(IllegalArgumentException e) { ... }

// after
@ServerExceptionMapper
public Response map(IllegalArgumentException e) { ... }
Defensive patterns

Strategy: validation

Validate before calling

java.lang.reflect.Method m = ...; // annotated mapper
if (java.lang.reflect.Modifier.isStatic(m.getModifiers())) {
    throw new IllegalStateException("@ServerExceptionMapper methods must not be static: " + m);
}

Type guard

static boolean isInstanceMapper(java.lang.reflect.Method m) {
    return !java.lang.reflect.Modifier.isStatic(m.getModifiers());
}

Prevention

When it happens

Trigger: Declaring a @ServerExceptionMapper or @Provider-annotated mapper method with the static modifier, detected during build-time generation.

Common situations: Writing stateless mappers as static 'utility' methods, converting helper methods to static after adding the annotation, or copying Java style from non-CDI code.

Related errors


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