Search code examples
javaandroidmethodhandle

NoSuchMethodError: No virtual method invoke in MethodHandle, Android


I am trying to use the MethodHandle on Android for a project. At the moment, I'm converting some existing Java code to be compatible with Android, but I've run into a problem.

In plain Java 7/8, the following compiles and prints "Jim":

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;

public class Example {

    public static void main(String[] args) throws Throwable {
        MethodHandle arrayReader = MethodHandles.arrayElementGetter(String[].class);

        Object array = new String[]{"Hi", "there", "Jim"};
        Object item = arrayReader.invoke(array, 2); 
        System.out.println(item);
    }   

}

The same code compiles for Android, but an exception is thrown at runtime:

java.lang.NoSuchMethodError: No virtual method invoke(Ljava/lang/Object;I)Ljava/lang/Object; in class Ljava/lang/invoke/MethodHandle; or its super classes (declaration of 'java.lang.invoke.MethodHandle' appears in /system/framework/core-oj.jar)

MethodHandle.invoke exists and uses the varargs feature to pass any number of Object arguments, yet at runtime it tries to find a method with arity 2 with parameter types Object and int.

I have tried replacing the invoke call with an array parameter: arrayReader.invoke(new Object[]{array, 2}), but this just creates another problem:

java.lang.UnsupportedOperationException: MethodHandle.invoke cannot be invoked reflectively.

I wouldn't have expected this to work anyway, since the MethodHandle produced by the MethodHandles.arrayElementGetter call takes two arguments (the array and the index), but I thought it was worth a shot.

I am running an Android emulator with API level 26. This is a portion of the build.gradle file:

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        minSdkVersion 26
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
...

Is there any way to fix this, or an alternative method to achieve the same result?


Solution

  • I fixed my own problem:
    I upgraded Android studio to version 3, and upgraded all the required plugin versions, e.g. the build tools, Gradle to version 4, and this fixed the problem. Reading this article prompted me to upgrade: pnfsoftware.com/blog/… (although it doesn't specifically mention upgrading Android studio to this version).