Skip to content

When graphql-java 17.x is an implementation dependency of a gradle project, it pulls in guava. #2540

@StrangeNoises

Description

@StrangeNoises

Describe the bug
It appears that graphql-java is not supposed to have a runtime dependency on Guava, because the main jar artifact is an output of shadowJar, which embeds guava underneath the graphql package namespace. And indeed, guava is not listed as a dependency in the pom. And yet, when you build a project using gradle to depend on graphql-java 17.x, guava (and several of its dependencies) are pulled into its dependency graph.

This appears to be because gradle will prefer the data in the generated graphql-java-17.2.module file, being directed to do so by a comment in the pom. The pom has its guava dependency edited out in build, but the .module file is unchanged.

This probably applies to antlr4 as well. (I think antlr4-runtime is supposed to be there but not plain antlr4?)

This did not occur with graphql 16.2. It appears it starts with 17.0, and continues with 17.2.

To Reproduce
Attached is a trivial gradle project called graphql-depender because all it does is depend on graphql-java. It's made by creating a default gradle java application project (using gradle init), editing build.gradle and removing the default guava dependency and adding an implementation dependency on graphl-java 17.2, in the form:

    implementation 'com.graphql-java:graphql-java:17.2'

graphql-depender.tar.gz

Unpack the jar, and run:

./gradlew installDist

You will see that app/build/install/app/lib contains a number of jars, including guava and its dependencies.

Show the dependency tree:

./gradlew --console=plain  app:dependencies --configuration runtimeClasspath

> Task :app:dependencies

------------------------------------------------------------
Project ':app'
------------------------------------------------------------

runtimeClasspath - Runtime classpath of source set 'main'.
\--- com.graphql-java:graphql-java:17.2
     +--- org.antlr:antlr4-runtime:4.9.2
     +--- org.slf4j:slf4j-api:1.7.30
     +--- com.google.guava:guava:30.0-jre
     |    +--- com.google.guava:failureaccess:1.0.1
     |    +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
     |    +--- com.google.code.findbugs:jsr305:3.0.2
     |    +--- org.checkerframework:checker-qual:3.5.0
     |    +--- com.google.errorprone:error_prone_annotations:2.3.4
     |    \--- com.google.j2objc:j2objc-annotations:1.3
     +--- com.graphql-java:java-dataloader:3.1.0
     |    \--- org.slf4j:slf4j-api:1.7.30
     +--- org.reactivestreams:reactive-streams:1.0.2
     \--- org.antlr:antlr4:4.9.2
          +--- org.antlr:antlr4-runtime:4.9.2
          +--- org.antlr:antlr-runtime:3.5.2
          +--- org.antlr:ST4:4.3
          |    \--- org.antlr:antlr-runtime:3.5.2
          +--- org.abego.treelayout:org.abego.treelayout.core:1.0.3
          +--- org.glassfish:javax.json:1.0.4
          \--- com.ibm.icu:icu4j:61.1

(*) - dependencies omitted (listed previously)

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

BUILD SUCCESSFUL in 468ms
1 actionable task: 1 executed

Workaround

I have a workaround, which I'm not entirely sure is correct, which is to exclude the transitive dependencies I don't want (ie: don't think are really required) in the dependency declaration like this:

    implementation('com.graphql-java:graphql-java:17.2') {
        exclude group: 'com.google.guava'
        exclude group: 'org.antlr', module: 'antlr4'
    }

This appears to work:

./gradlew --console=plain  app:dependencies --configuration runtimeClasspath

> Task :app:dependencies

------------------------------------------------------------
Project ':app'
------------------------------------------------------------

runtimeClasspath - Runtime classpath of source set 'main'.
\--- com.graphql-java:graphql-java:17.2
     +--- org.antlr:antlr4-runtime:4.9.2
     +--- org.slf4j:slf4j-api:1.7.30
     +--- com.graphql-java:java-dataloader:3.1.0
     |    \--- org.slf4j:slf4j-api:1.7.30
     \--- org.reactivestreams:reactive-streams:1.0.2

(*) - dependencies omitted (listed previously)

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

BUILD SUCCESSFUL in 558ms
1 actionable task: 1 executed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions