quarkusio/quarkus · error · DeploymentException

JAX-RS Application class '${applicationClassInfo.name()}' co

Error message

JAX-RS Application class '${applicationClassInfo.name()}' contains multiple conflicting @Blocking, @NonBlocking and @RunOnVirtualThread annotations.

What it means

The JAX-RS Application class declares more than one of @Blocking, @NonBlocking, or @RunOnVirtualThread at the class level. These annotations all define the default execution model for the application, so only one may be present; declaring several is contradictory.

Source

Thrown at independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/scanning/ResteasyReactiveScanner.java:137

                    | InvocationTargetException e) {
                throw new RuntimeException("Unable to handle class: " + applicationClass, e);
            }
            // collect default behaviour, making sure that we don't have multiple contradicting annotations
            int numAnnotations = 0;
            if (applicationClassInfo.hasDeclaredAnnotation(ResteasyReactiveDotNames.BLOCKING)) {
                blocking = BlockingDefault.BLOCKING;
                numAnnotations++;
            }
            if (applicationClassInfo.hasDeclaredAnnotation(ResteasyReactiveDotNames.NON_BLOCKING)) {
                blocking = BlockingDefault.NON_BLOCKING;
                numAnnotations++;
            }
            if (applicationClassInfo.hasDeclaredAnnotation(ResteasyReactiveDotNames.RUN_ON_VIRTUAL_THREAD)) {
                blocking = BlockingDefault.RUN_ON_VIRTUAL_THREAD;
                numAnnotations++;
            }
            if (numAnnotations > 1) {
                throw new DeploymentException("JAX-RS Application class '" + applicationClassInfo.name()
                        + "' contains multiple conflicting @Blocking, @NonBlocking and @RunOnVirtualThread annotations.");
            }
        }
        if (selectedAppClass != null) {
            globalNameBindings = NameBindingUtil.nameBindingNames(index, selectedAppClass);
        }
        return new ApplicationScanningResult(allowedClasses, singletonClasses, excludedClasses, globalNameBindings,
                filterClasses, application,
                selectedAppClass, blocking);
    }

    public static SerializerScanningResult scanForSerializers(IndexView index,
            ApplicationScanningResult applicationScanningResult) {

        Collection<ClassInfo> readers = index
                .getAllKnownImplementors(ResteasyReactiveDotNames.MESSAGE_BODY_READER);
        List<ScannedSerializer> readerList = new ArrayList<>();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Keep exactly one of @Blocking, @NonBlocking, or @RunOnVirtualThread on the Application class.
  2. Set the execution model per-resource-method instead of at the Application level when mixing models is intended.
  3. Configure the default execution model via quarkus.resteasy-reactive.* config properties rather than annotations.

Example fix

// before
@Blocking
@RunOnVirtualThread
class MyApp extends Application { }
// after
@RunOnVirtualThread
class MyApp extends Application { }
Defensive patterns

Strategy: validation

Validate before calling

long n = java.util.Arrays.stream(appClass.getAnnotations())
        .map(a -> a.annotationType().getSimpleName())
        .filter(nm -> nm.equals("Blocking") || nm.equals("NonBlocking") || nm.equals("RunOnVirtualThread"))
        .count();
if (n > 1) throw new IllegalStateException("Only one execution-model annotation allowed on " + appClass);

Prevention

When it happens

Trigger: scanForApplicationClass counts declared annotations among BLOCKING, NON_BLOCKING, RUN_ON_VIRTUAL_THREAD on the Application class; if numAnnotations > 1 it throws this DeploymentException.

Common situations: Adding @RunOnVirtualThread to an Application that already had @Blocking (or @NonBlocking) while migrating to virtual threads; copy-pasting annotation blocks between Application classes.

Related errors


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