quarkusio/quarkus · error · RuntimeException
More than one Application class: ${jakartaRestApplicationCla
Error message
More than one Application class: ${jakartaRestApplicationClasses} What it means
During deployment, ResteasyServerCommonProcessor scans the application index for concrete subclasses of jakarta.ws.rs.core.Application to determine the application path and which classes that Application selects. JAX-RS allows at most one Application subclass, so when more than one non-abstract Application class is found the build fails with this RuntimeException.
Source
Thrown at extensions/resteasy-classic/resteasy-server-common/deployment/src/main/java/io/quarkus/resteasy/server/common/deployment/ResteasyServerCommonProcessor.java:233
final Set<String> excludedClasses;
if (resteasyConfig.buildTimeConditionAware()) {
excludedClasses = getExcludedClasses(buildTimeConditions);
} else {
excludedClasses = Collections.emptySet();
}
final Set<String> allowedClasses;
final String appClass;
if (resteasyConfig.ignoreApplicationClasses()) {
applicationPath = null;
allowedClasses = Collections.emptySet();
appClass = null;
} else {
Collection<ClassInfo> jakartaRestApplicationClasses = index.getAllKnownSubclasses(ResteasyDotNames.APPLICATION)
.stream()
.filter(ci -> !ci.isAbstract()).collect(
Collectors.toSet());
if (jakartaRestApplicationClasses.size() > 1) {
throw new RuntimeException("More than one Application class: " + jakartaRestApplicationClasses);
}
if (jakartaRestApplicationClasses.isEmpty()) {
applicationPath = null;
allowedClasses = Collections.emptySet();
appClass = null;
} else {
ClassInfo jakartaRestApplicationClass = jakartaRestApplicationClasses.iterator().next();
applicationPath = jakartaRestApplicationClass.annotation(ResteasyDotNames.APPLICATION_PATH);
allowedClasses = getAllowedClasses(jakartaRestApplicationClass);
appClass = jakartaRestApplicationClass.name().toString();
}
jaxrsProvidersToRegisterBuildItem = getFilteredJaxrsProvidersToRegisterBuildItem(
jaxrsProvidersToRegisterBuildItem, allowedClasses, excludedClasses);
}
boolean filterClasses = !allowedClasses.isEmpty() || !excludedClasses.isEmpty();
View on GitHub (pinned to e1c734241f)
Solutions
- Delete or make abstract all but one jakarta.ws.rs.core.Application subclass in your project.
- Exclude the dependency JAR containing the extra Application class, or override/shade it out.
- If you need multiple paths, use a single Application with @ApplicationPath and split resources by path annotations, or migrate to Quarkus REST (RESTEasy Reactive) which doesn't require Application classes.
Example fix
// before
@ApplicationPath("/api")
public class App1 extends Application {}
@ApplicationPath("/v2")
public class App2 extends Application {} // build fails
// after
@ApplicationPath("/api")
public class App extends Application {} Defensive patterns
Strategy: validation
Validate before calling
long count = Stream.concat(Arrays.stream(MyApplicationClasses.class.getDeclaredClasses()),
// plus scan your dependencies
Arrays.stream(knownAppClasses))
.filter(c -> !Modifier.isAbstract(c.getModifiers()))
.filter(jakarta.ws.rs.core.Application.class::isAssignableFrom)
.count();
if (count > 1) throw new IllegalStateException("Only one concrete Application class is allowed: found " + count); Type guard
static boolean isConcreteApplication(Class<?> c) {
return jakarta.ws.rs.core.Application.class.isAssignableFrom(c) && !Modifier.isAbstract(c.getModifiers());
} Try / catch
// This fails during Quarkus deployment (augmentation), so it cannot be caught at runtime. // Guard instead in a build-time check or CI test: // fail the build if more than one concrete Application subclass is on the classpath.
Prevention
- Keep exactly one jakarta.ws.rs.core.Application subclass per application
- Search dependency JARs (jdeps / archunit test) for classes extending Application before adding them
- Delete unused/renamed Application classes instead of leaving them in place
When it happens
Trigger: Declaring two or more non-abstract classes extending jakarta.ws.rs.core.Application (with or without @ApplicationPath) in the same Quarkus application or its dependency JARs, triggering deployment build of the RESTEasy Classic server extension.
Common situations: Copy-pasting an Application class from another app; adding a library that itself ships an Application subclass; refactoring renamed Application classes leaving the old one behind.
Related errors
- Usage of '@Inject' is not allowed in 'jakarta.ws.rs.core.App
- Unable to handle class: ${applicationClass}
- Non static nested resources classes are not supported: '
- Method '' of class '' contains multiple HTTP method annotati
- Resource method '%s#%s' can only have a single body paramete
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/79008a4c46ffa87c.
Report an issue: GitHub.