Christian
Christian

Reputation: 313

Gradle transient dependency resolution: How to generically prefer `guava-jre` over `guava-android`?

My project transitively depends on Google Guava lib. Suddenly (with new version of Guava?) the application crashes at startup with
java.lang.NoSuchMethodError: 'java.util.stream.Collector com.google.common.collect.ImmutableList.toImmutableList()'.

In Guava 29.0, this method is missing in 29.0-android, but available with 29.0-jre. Unfortunately, Gradle's dependency resolution chooses 29.0-android.

In a first attempt I fixed it in build.gradle like this:

configurations.all {
  resolutionStrategy.dependencySubstitution {
    // Because of java.lang.NoSuchMethodError: 'java.util.stream.Collector com.google.common.collect.ImmutableList.toImmutableList()'
    substitute module('com.google.guava:guava:29.0-android') with module('com.google.guava:guava:29.0-jre')
  }
}

Is there a more generic way to resolve this issue? If next Guava version 30.0-android/-jre comes up, my solution has to get fixed again.

Upvotes: 4

Views: 1910

Answers (1)

Bjørn Vester
Bjørn Vester

Reputation: 7600

Until PR-3683 is merged in to make Guava publish Gradle metadata, which I am really looking forward to myself, you can use jjohannes' missing-metadata-guava plugin. It will retroactively add variants and capabilities to the Guava module metadata in Gradle. Along with some resolution rules, this ensures that the jre variant is selected even if a dependency transitively requests a (newer) android version.

Upvotes: 1

Related Questions