I’m having trouble when delegating to a Java interface with default methods.
Java library pulled in via Maven/Gradle:
interface JavaInterface {
default String foo() {
return "interface"
}
}
final class JavaInterfaceImpl implements JavaInterface {
@Override
public String foo() {
return "impl"
}
}
My Kotlin code:
class KotlinImpl(delegate: JavaInterface) : JavaInterface by delegate
fun test() {
val javaImpl = JavaInterfaceImpl()
val kotlinImpl = KotlinImpl(javaImpl)
kotlinImpl.foo() // "interface"
}
In this example, when calling kotlinImpl.foo()
I expect to get back "impl"
but instead I get back "interface"
. This is using Kotlin 1.5 (also observed in 1.4). I’ve played around with the -Xjvm-default
compiler flag to no avail.
This article seems to speak to this issue in the context of Java code calling Kotlin, but my problem is the other way around (Kotlin code calling a Java library). In this YouTrack issue, one of the comments calls out the same thing
Got bit by this today as well. In our case, the default method implementation was provided by an interface in a Java library, so even though we had
-Xjvm-defaults=enable
set on the Kotlin compiler, as discussed in the blog post, this did not fix the problem for us. I had to make the delegate available as a property in my Kotlin class and manually add an override for the problematic method to fix the problem.
I’m doing this with interfaces with lots of methods, so manually overriding each one doesn’t feel like a real solution. Is this a bug or just an unavoidable part of Kotlin/Java interop?