0

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?

AndreaF
  • 11,975
  • 27
  • 102
  • 168
  • What Java `rt.jar` good for inside APK/AAR? I find that highly questionable. – Martin Zeitler Nov 23 '22 at 00:57
  • @MartinZeitler It doesn't include rt.jar in App released, but it avoid optimization to strip away some Java SE libraries without the need to configure all special exception one by one. – AndreaF Nov 23 '22 at 01:02
  • Well, the Java SE SDK `rt.jar` has absolutely nothing to do with Android SDK `android.jar`. This does not belong into the package, because the target device has the runtime anyway. Don't mix Standard Edition (desktop) with Android Java (mobile). This means, even if you somehow manage to stuff it into the package, it's just bloat which might even be optimized (not packaged, because it's not being used). – Martin Zeitler Nov 23 '22 at 01:17
  • @MartinZeitler Of course it is not part of Android SDK (the point to include it is exactly this), but you are failing to understand the reason why I do this. I guess you have used thirdy party jars not part of Android SDK!?! That is what I'm doing, the only difference is that these are also part of Java Se and I avoid a lot of time wasted in keep this keep that in obfuscator config with just a code line, including rt.jar is nothing more than a whitelist trick for shrinker/obfuscator in this case. – AndreaF Nov 23 '22 at 01:24
  • Consider the whole resulting apk is just 7MB (and it doesn't include any native code that may cause compatibility issues). I have used this method for long time, the problem is only with R8 shrinker now that I have migrated my code to Java 11 due to jmods. – AndreaF Nov 23 '22 at 01:37
  • The target device has `rt.jar` and `android.jar`... and this `rt.jar` will not be processed anyway. And you don't even have to use R8, but ProGuard can still be applied: https://github.com/Guardsquare/proguard – Martin Zeitler Nov 23 '22 at 10:36

1 Answers1

0

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.

sgjesse
  • 3,793
  • 14
  • 17