Gradle Module Metadata makes Guava's -android version dangerous for libraries #7575
Open
2 tasks done
Labels
type=defect
Bug, not working as expected
Guava Version
Noticed on 33.2.1-android because of an old PR, but currently using 33.3.1-android
Description
TL;DR: Gradle uses the Module Metadata to use -jre version, but Maven and AGP will use -android meaning we compile and test with a superset of what our users will use.
In gRPC Java we mostly use Guava's -android versions because we support older Android versions. We also use the Gradle build system. However, we discovered that when compiling the -jre version is actually what's being used.
gradle dependencies
shows -android, but the jar file passed to javac is -jre.This was quite the riddle until I remembered Guava uses Gradle Module Metadata, and yep, the -android version pulls in the -jre version. See also #7154
gRPC Java is a library, and used by Maven and Android users. While Gradle used the -jre version to compile, the published artifacts still depend on the -android version. So Maven and Android users will use -android. This means it is possible for -jre-only symbols to be used accidentally and then cause runtime failures when unavailable.
Most cases when -jre symbols are used will cause animalnsiffer failures, because it uses APIs not available on the target platform. But that is not universally the case. For example, the way we noticed this was
Predicate.test()
. The -jre version provides the test() method, because it extendsjava.util.function.Predicate
. But the -android version does not even though it could without requiring Java 8 APIs.Example
Expected Behavior
Javac could not find symbol Predicate.test().
Actual Behavior
./gradlew compileJava
succeeds.Packages
No response
Platforms
No response
Checklist
I agree to follow the code of conduct.
I can reproduce the bug with the latest version of Guava available.
The text was updated successfully, but these errors were encountered: