Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android + coreLibraryDesugaring: which Java 11 APIs can I expect to work?

I'm trying to migrate some Java library from 'normal' JVM to android and stuck with some Java11 APIs used in the code.

The first thing I already got - Java11 language features seems to work only with Canary build of Android Studio, see answer here

Now I need to get understanding about which APIs can be really used. Here are two use-cases which do not work for me and I can't get if I'm doing something wrong or it never should work:

  1. List.copyOf() - introduced in Java11, method copyOf is not available on android. Methods 'List.of()', introduced with Java 9, work OK.

  2. class java.lang.invoke.LambdaMetafactory - introduced with Java 1.8 - to be used for programmatic creation of lambdas for usage instead for reflection, is not visible on Android.

I see both of them in sources of desugar_jdk_libs here:

  • https://github.com/google/desugar_jdk_libs/blob/master/jdk11/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java
  • https://github.com/google/desugar_jdk_libs/blob/master/src/share/classes/java/util/List.java

So - the question is: how can I identify if some Java API is supposed to be available in 'desugared' android build or no? What really can be expected from 'desugaring'?

Steps to reproduce:

  1. Using Android Studio Canary generate a dummy "Basic Activity" project
  2. Make sure following is provided in build.gradle
android {
    compileOptions {
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
    }
}
dependencies {
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}
  1. Add following lines somewhere in code
        List<Integer> ints1 = List.of(1, 2, 3);
        Supplier<List<Object>> listSupplier = () -> new ArrayList<>();
        List<Object> alist = listSupplier.get();

        List<Integer> ints2 = List.copyOf(ints1);
        LambdaMetafactory.metafactory(null,null,null,null,null,null);

Last 2 lines fail to compile for me.

PS: final application is supposed to work on Android 10+.

like image 824
Xtra Coder Avatar asked Mar 10 '21 00:03

Xtra Coder


1 Answers

Desugaring lib is considered unofficial. We can't expect an exact answer. We get the feature when it is ready. Now List.copyOf() method now working with the latest Gradle version.

About the LambdaMetafactory class, It is not included in Android Javadoc. This means we assume we don't have LambdaMetafactory at all. Google stripped down some java API for being lightweight.

In general, We should check android Javadoc first. If android Javadoc has no mention about some API. We can be sure we won't get that feature anytime soon.

like image 94
hurelhuyag Avatar answered Sep 28 '22 06:09

hurelhuyag