-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
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'
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