VerifyError on Kitkat when code explicitly calls a default method

51 Views Asked by At

When instantiating a class that has code to explicitly call a default method for an interface that it implements, a java.lang.VerifyError is thrown. This happens on Kitkat (API 19), but Lollipop and more recent versions work fine. The default method I'm working with was added in Android 12 (API 31), but I have a build version check, so that line won't even execute on earlier versions, but Kitkat still throws the error.

public class MyInputConnection implements InputConnection {
    private void foo() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            SurroundingText surroundingText = InputConnection.super.getSurroundingText(1, 1, 0);
            //...
        }
    }
}
MyInputConnection ic = new MyInputConnection(this); // error thrown here

Logs before the error:

W/dalvikvm: DexOpt: method is in an interface

I/dalvikvm: Could not find method android.view.inputmethod.InputConnection.getSurroundingText, referenced from method com.ewittman.example.MyInputConnection.foo

W/dalvikvm: VFY: unable to resolve virtual method 44: Landroid/view/inputmethod/InputConnection;.getSurroundingText (III)Landroid/view/inputmethod/SurroundingText;

VFY: rejecting opcode 0x6f at 0x0008

VFY: rejected Lcom/ewittman/example/MyInputConnection;.foo ()V Verifier rejected class Lcom/ewittman/example/MyInputConnection;

Error:

java.lang.VerifyError: com/ewittman/example/MyInputConnection

Why is this error getting thrown on Kitkat? Since the line of code to call the default method won't even be executed on Kitkat, I'd expect the class to instantiate without error.

I could create a new dummy implementation of the interface that doesn't override the default method so I can call that, but that doesn't seem like a very clean solution. Is there a better way to allow directly calling the default method for versions that include the method that won't break older versions?

0

There are 0 best solutions below