quarkusio/quarkus · error · RestClientDefinitionException
Using Kotlin default methods on interfaces that are not back
Error message
Using Kotlin default methods on interfaces that are not backed by Java 8 default interface methods is not supported. See https://kotlinlang.org/docs/java-to-kotlin-interop.html#default-methods-in-interfaces for more details. Offending interface is '${interface}'. What it means
Kotlin interfaces compile default methods into a synthetic `DefaultImpls` class instead of Java 8 default interface methods unless the Kotlin compiler flag `-Xjvm-default=all` (or `all-compatibility`) is used. The REST Client runtime proxy cannot invoke these, so Quarkus detects `...DefaultImpls` in the index for an annotated Kotlin interface and throws RestClientDefinitionException.
Source
Thrown at extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java:964
defaultPriority);
} else {
AnnotationInstance priorityAnnoOnProvider = providerClass.declaredAnnotation(ResteasyReactiveDotNames.PRIORITY);
if (priorityAnnoOnProvider != null) {
priority = priorityAnnoOnProvider.value().asInt();
}
}
return priority;
}
// By default, Kotlin does not use Java interface default methods, but generates a helper class that contains the implementation.
// In order to avoid the extra complexity of having to deal with this mode, we simply fail the build when this situation is encountered
// and provide an actionable error message on how to remedy the situation.
private void validateKotlinDefaultMethods(ClassInfo jaxrsInterface, IndexView index) {
if (jaxrsInterface.declaredAnnotation(KOTLIN_METADATA_ANNOTATION) != null) {
var potentialDefaultImplClass = DotName
.createSimple(jaxrsInterface.name().toString() + KOTLIN_INTERFACE_DEFAULT_IMPL_SUFFIX);
if (index.getClassByName(potentialDefaultImplClass) != null) {
throw new RestClientDefinitionException(String.format(
"Using Kotlin default methods on interfaces that are not backed by Java 8 default interface methods is not supported. See %s for more details. Offending interface is '%s'.",
"https://kotlinlang.org/docs/java-to-kotlin-interop.html#default-methods-in-interfaces",
jaxrsInterface.name().toString()));
}
}
}
private boolean isRestMethod(MethodInfo method) {
if (!Modifier.isAbstract(method.flags())) {
return false;
}
for (AnnotationInstance annotation : method.annotations()) {
if (annotation.target().kind() == AnnotationTarget.Kind.METHOD
&& BUILTIN_HTTP_ANNOTATIONS_TO_METHOD.containsKey(annotation.name())) {
return true;
} else if (annotation.name().equals(ResteasyReactiveDotNames.PATH)) {
return true;
}View on GitHub (pinned to e1c734241f)
Solutions
- Add `kotlinOptions.freeCompilerArgs += "-Xjvm-default=all"` to the Kotlin compile task in build.gradle(.kts) (or `<compilerArgs><arg>-Xjvm-default=all</arg></compilerArgs>` in Maven)
- Enable `jvmDefault = "all"` in the Kotlin toolchain
- Move default implementations out of the client interface into an abstract class or helper
Example fix
// before (build.gradle.kts)
tasks.withType<KotlinCompile> { kotlinOptions.jvmTarget = "17" }
// after
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "17"
kotlinOptions.freeCompilerArgs += "-Xjvm-default=all"
} Defensive patterns
Strategy: validation
Validate before calling
// build.gradle.kts check
val usesJvmDefaultAll = kotlin {
compilerOptions { freeCompilerArgs.add("-Xjvm-default=all") }
}
// Quick pre-check: ensure DefaultImpls classes are absent for client interfaces
val bad = listOf("MyClient")
.map { Class.forName(it + "$DefaultImpls") }
if (bad.isNotEmpty()) error("Enable -Xjvm-default=all; DefaultImpls found") Prevention
- Set -Xjvm-default=all (or all-compatibility) in every Kotlin module containing REST Client interfaces
- Avoid default method bodies in client interfaces; use overloads or helper functions
- Check third-party Kotlin libraries for DefaultImpls classes before using them as clients
When it happens
Trigger: Declaring a REST Client interface in Kotlin with default method bodies (or @JvmDefault-less compilation) and building without `-Xjvm-default=all`.
Common situations: Kotlin projects created with old Kotlin versions before jvm-default defaults; adding a default method to a client interface for convenience; shared Kotlin library compiled without the flag.
Related errors
- 'quarkus-narayana-lra' can only work if 'quarkus-rest-client
- io.quarkus.oidc.client.OidcClientFilter annotation can be ap
- Companions are not supported in Java.
- Not possible to define the scope %s for the REST client %s
- @RegisterClientContextResolver is only supported on static m
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/2ce02122cd9110d2.
Report an issue: GitHub.