How to include jmods with R8 in Android?

180 views Asked by At

With older JDK versions I included rt.jar in R8 configuration with

-libraryjars <java.home>/lib/rt.jar

In order to meet requirements of various java libraries not Android-specific (NOTE this doesn't mean that whole rt.jar will be included in App, it's just a practical way to avoid R8 optimization to strip away important Java SE code without configuring all keep whitelist one by one)

With JDK above 8 rt.jar is no longer available and it has been replaced by jmods, searching seems the proguart syntax to include equivalent jmods alternative to rt.jar seems to be

-libraryjars  <java.home>/jmods/java.base.jmod(!**.jar,!module-info.class)

So I have tried it, but unfortunately with R8 I get this error:

Unexpected input type. Only archive types are supported, e.g., .jar, .zip, etc.

What is the correct way to include it?

1

There are 1 answers

0
sgjesse On

When R8 is not used for Android projects (where android.jar is the runtime library) one needs the Java runtime library, which was in rt.jar until Java 8. For later JDKs a file system provider is included in $JAVA_HOME/lib/jrt-fs.jar. R8 has support for using that by passing the JAVA_HOME directory as the library path to R8, so:

  $JAVA_HOME/bin/java -cp r8-jar com.android.tools.r8.R8 --lib $JAVA_HOME ...

Will work for all JDK versions. If the JAVA_HOME has a rt.jar that is used and otherwise the file system provider is used to find the runtime library. See the code for handling this here.

Note, this does not work when using -libraryjars in a configuration file, only for the --lib argument directly to R8. Opened issue 260213385 on that.

Also note that, that when the file system provider is loaded it will always expose the runtime of the running JVM, so doing this

  $JAVA_HOME_1/bin/java -cp r8-jar com.android.tools.r8.R8 --lib $JAVA_HOME_2 ...

you will still see the the runtime of JAVA_HOME_1 if JAVA_HOME_2 is for JDK-9 or newer.