Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradle Module Metadata makes Guava's -android version dangerous for libraries #7575

Open
2 tasks done
ejona86 opened this issue Dec 23, 2024 · 0 comments
Open
2 tasks done
Labels
type=defect Bug, not working as expected

Comments

@ejona86
Copy link

ejona86 commented Dec 23, 2024

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 extends java.util.function.Predicate. But the -android version does not even though it could without requiring Java 8 APIs.

Example

In a build.gradle:

dependencies {
  implementation 'com.google.guava:guava:33.2.1-android'
}


In a Foo.java:


final class Foo {
  public boolean foo(com.google.common.base.Predicate<Object> p) {
    return p.test(null);
  }
}

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.

@ejona86 ejona86 added the type=defect Bug, not working as expected label Dec 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type=defect Bug, not working as expected
Projects
None yet
Development

No branches or pull requests

1 participant