Skip to content

Gradle unable to resolve Guava in a project, with a VariantSelectionByAttributesException error #8398

Open

Description

@fidothe

Guava Version

33.5.0

Description

In a gradle project I have a build that uses some Java tooling as part of its
build machinery, but is not, itself, a Java project. One of the tooling
dependencies (javaparser) has a dependency on Guava.

For historical reasons that project's build.gradle.kts applied the
java-library plugin. When I removed it because its default tasks were causing
problems with other tasks and, as noted, no Java artifacts were being produced,
the build failed with an error:

Variant Selection Exception: 
    org.gradle.internal.component.resolution.failure.exception.VariantSelectionByAttributesException 
    caused by Resolution Failure: 
    org.gradle.internal.component.resolution.failure.type.NoCompatibleVariantsFailure

Gradle can no longer resolve a Guava variant that it can use. Note that javaparser is explicitly depending on the -jre Guava version. (https://github.com/javaparser/javaparser/blob/11a99ae61df28b19fb9b64e5f7c216fa71dc4020/pom.xml#L432-L437)

There's a minimal repro here: https://github.com/Saxonica/guava-variant-problem

This project contains two Gradle sub-projects, java_lib and
non_java whose build.gradle.kts differ only in the plugin they apply.

non_java applies the base plugin, and java_lib applies the java-library
plugin. They both contain a simple configuration which declares a dependency on
Guava.

Running ./gradlew java_lib:dependencies shows that Guava resolves fine, and
./gradlew non_java:depdendencies shows the failure.

This is defintely unexpected behvaiour, and seems like buggy behaviour, though I
am really not sure if this is a Gradle problem or a Guava Gradle metadata
problem.

I imagine this is related to #7059, #6801 and friends

Example

Clone https://github.com/Saxonica/guava-variant-problem and run the following:


./gradlew non_java:dependencies`

Expected Behavior

A properly resolved dependency tree, whose macguffin configuration's dependency tree should be identical to the result of running ./gradlew java_lib:dependencies:

> Task :non_java:dependencies

------------------------------------------------------------
Project ':non_java'
------------------------------------------------------------

macguffin
\--- com.google.guava:guava:33.6.0-jre
     +--- com.google.guava:failureaccess:1.0.3
     +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
     +--- org.jspecify:jspecify:1.0.0
     +--- com.google.errorprone:error_prone_annotations:2.47.0
     \--- com.google.j2objc:j2objc-annotations:3.1

macguffinRuntime (n)
\--- com.google.guava:guava:33.6.0-jre (n)

(n) - A dependency or dependency configuration that cannot be resolved.

A web-based, searchable dependency report is available by adding the --scan option.

BUILD SUCCESSFUL in 414ms

Actual Behavior

> Task :non_java:dependencies

------------------------------------------------------------
Project ':non_java'
------------------------------------------------------------

macguffin
\--- com.google.guava:guava:33.6.0-jre FAILED

macguffinRuntime (n)
\--- com.google.guava:guava:33.6.0-jre (n)

(n) - A dependency or dependency configuration that cannot be resolved.

A web-based, searchable dependency report is available by adding the --scan option.

BUILD SUCCESSFUL in 414ms

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.

Activity

  1. dokson commented on May 3, 2026

    @dokson

    Hi @fidothe — the linked repro at https://github.com/Saxonica/guava-variant-problem returns 404. Could you confirm whether the repo was moved, renamed, or made private? An updated link (or a gist with the two build.gradle.kts files) would help anyone trying to investigate. Thanks!

  2. fidothe commented on May 3, 2026

    @fidothe
    Author

    Apologies, that repo has been made public now.

  3. dokson commented on May 3, 2026

    @dokson

    Not a maintainer, just chiming in with a verified workaround.

    I cloned the reproducer and confirmed both the failure and a one-line fix on the consumer side.

    Why it fails. Guava's Gradle Module Metadata declares the standard org.gradle.jvm.environment attribute (standard-jvm / android) on every variant — that's what lets Gradle disambiguate -jre from -android automatically (the reason Guava adopted GMM, cf. #6801). The JVM plugins (java, java-base, java-library) register an AttributesSchema with compatibility/disambiguation rules for that attribute and its companions (usage, libraryelements, category, bundling). The base plugin does not, so Gradle has no rules to match the producer's variants against an empty consumer-side attribute set, hence NoCompatibleVariantsFailure.

    Workaround (one line). Gradle ships a plugin meant exactly for this case — consuming JVM libraries from a non-JVM project. In non_java/build.gradle.kts:

    plugins {
      base
      `jvm-ecosystem`
    }

    jvm-ecosystem registers the JVM attributes schema without producing any Java artifacts or tasks. With it applied, on your reproducer:

    > Task :non_java:dependencies
    macguffin
    \--- com.google.guava:guava:33.6.0-jre
         +--- com.google.guava:failureaccess:1.0.3
         +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
         +--- org.jspecify:jspecify:1.0.0
         +--- com.google.errorprone:error_prone_annotations:2.47.0
         \--- com.google.j2objc:j2objc-annotations:3.1
    

    i.e. identical to the java_lib output. Verified locally with Gradle 9.5 and Guava 33.6.0-jre.

    Reference: https://docs.gradle.org/current/userguide/jvm_ecosystem_plugin.html

    Whether this is something Guava should document for non-JVM consumers, or whether the metadata should be adjusted, is up to the maintainers — but at least there's a working fix in the meantime.

  4. fidothe commented on May 5, 2026

    @fidothe
    Author

    @dokson Thanks for that. I also later found that advice from the Gradle forums.

    I guess my question for the Guava maintainers is whether this needs to be mitigated with documentation, or if there are changes to the Gradle metadata which would make it work.

    I would have assumed that explicitly depending on the -jre version, as javaparser does, would help with disambiguating, but it's really unclear from the Gradle documentation.

    In any case, it seems like providing Gradle module metadata is enough to make Gradle be much more restrictive in how it decides on which artifact versions are acceptable. Our use case, where we're using javaparser to produce information we need to transpile Java code to C#, may be a little unusual, but the general pattern of using java dependencies in build tooling for building non-java things doesn't seem that unusual at all.

  5. added
    type=documentationDocumentation that is other than for an API
    P4no SLO
    and removed
    type=defectBug, not working as expected
    on May 7, 2026
  6. giruuuuj commented on May 22, 2026

    @giruuuuj

    This issue has been resolved by PR #8442.

    Root cause: Guava publishes Gradle Module Metadata declaring org.gradle.jvm.environment on all variants. Projects without the jvm-ecosystem or java-library plugin cannot resolve Guava because they lack the attribute schema needed to match these variants.

    Fix: Added two new fallback variants (apiElements, runtimeElements) to module.json that omit the org.gradle.jvm.environment attribute. When a consumer does not declare JVM environment attributes, Gradle falls back to these variants.

    Workaround for older versions: Apply the jvm-ecosystem plugin in your build script:

    plugins {
      base
      `jvm-ecosystem`
    }

    See #8442 for the full implementation.

  7. pangwangshu commented on Aug 4, 2026

    @pangwangshu
    Contributor

    Is it still open? My PR added corrected the document.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P4no SLOtype=documentationDocumentation that is other than for an API

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions