Kotlin / binary-compatibility-validator

Public API management tool
Apache License 2.0
763 stars 55 forks source link

Synthetic static method "InterfaceName$default" that used to resolve default arguments is not included to apiDump #142

Open antohaby opened 1 year ago

antohaby commented 1 year ago

This change is binary incompatible in Kotlin (current version 1.9.0)

v1

interface Foo {
 fun bar(name: String = "bar") 
}

v2

interface Bar {
 fun bar(name: String = "bar") 
}
interface Foo : Bar

At runtime, it fails with: NoSuchMethodError: Foo.bar$default...

However, BCV doesn't write this synthetic method to the API dump file. Thus this change is undetectable by BCV.

fzhinkin commented 7 months ago

The dump for v1 should look like:

public abstract interface class cases/default/Foo {
    public abstract fun bar (Ljava/lang/String;)V
}

public final class cases/default/Foo$DefaultImpls {
    public static synthetic fun bar$default (Lcases/default/Foo;Ljava/lang/String;ILjava/lang/Object;)V
}

and for v2 it should be:

public abstract interface class cases/default/Bar {
    public abstract fun bar (Ljava/lang/String;)V
}

public final class cases/default/Bar$DefaultImpls {
    public static synthetic fun bar$default (Lcases/default/Bar;Ljava/lang/String;ILjava/lang/Object;)V
}

public abstract interface class cases/default/Foo : cases/default/Bar {
}

However, the runtime error would be about missing DefaultImpls class, not the method.

Do you have a reproducer for the issue with NoSuchMethodError: Foo.bar$default...?