quarkusio/quarkus · error · java.lang.RuntimeException

Error checking value of member method ${methodName} on ${dec

Error message

Error checking value of member method ${methodName} on ${declaringClass}

What it means

Qualifiers.compareMembers/val1/val2 invoke annotation member methods reflectively to compare qualifier values. If the reflective invocation fails (IllegalArgumentException, IllegalAccessException, or InvocationTargetException), it is wrapped in a RuntimeException with this message and the original cause attached.

Source

Thrown at independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/Qualifiers.java:147

        }
        return false;
    }

    boolean isSubset(Set<Annotation> observedQualifiers, Set<Annotation> eventQualifiers) {
        for (Annotation required : observedQualifiers) {
            if (!hasQualifier(eventQualifiers, required)) {
                return false;
            }
        }
        return true;
    }

    private static Object invoke(Method method, Object instance) {
        try {
            method.setAccessible(true);
            return method.invoke(instance);
        } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(
                    "Error checking value of member method " + method.getName() + " on " + method.getDeclaringClass(), e);
        }
    }

    private void verifyQualifier(Class<? extends Annotation> annotationType) {
        if (!allQualifiers.contains(annotationType.getName())) {
            throw new IllegalArgumentException("Annotation is not a registered qualifier: " + annotationType);
        }
    }

    private static class TimesSeenBiFunction implements BiFunction<Class<? extends Annotation>, Integer, Integer> {

        private static final TimesSeenBiFunction INSTANCE = new TimesSeenBiFunction();

        private TimesSeenBiFunction() {
        }

        @Override

View on GitHub (pinned to e1c734241f)

Solutions

  1. Inspect the wrapped cause (getCause()) — it identifies the real failure (access, wrong instance, or member threw).
  2. Ensure qualifier members are simple constants (String/int/enum/Class/arrays) that cannot throw.
  3. Make sure qualifier annotations on beans and at lookup come from the same classloader/artifact version.
  4. In native mode, verify the qualifier annotation is part of the application's own code (auto-registered) and not built reflectively at runtime.

Example fix

// before
@Qualifier
@Retention(RUNTIME)
public @interface MyQ { String value() default System.getProperty("env"); } // can throw
// after
@Qualifier
@Retention(RUNTIME)
public @interface MyQ { String value(); } // constant at use site
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check that qualifier members are plain value members
for (Method m : qualifierType.getDeclaredMethods()) {
    if (m.getParameterCount() != 0 && !m.isDefault()) throw new IllegalStateException("Bad member: " + m);
}

Try / catch

try {
    compareQualifiers(q1, q2);
} catch (RuntimeException e) {
    if (e.getCause() instanceof InvocationTargetException) {
        log.error("Qualifier member threw during comparison", e.getCause().getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: A qualifier member method throwing an exception when invoked (e.g. member computes a value and fails), the annotation proxy instance is of the wrong type for the method, or access restrictions (module/JPMS, native-image) block the invocation.

Common situations: Custom qualifiers with member values computed by code that throws; comparing qualifier instances across classloaders so the method doesn't belong to the instance's class; native-image/GraalVM reaching methods not registered for reflection.

Related errors


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