I have a multi-module Gradle project. One module (A) contains database-related classes; another (B) contains Spark applications and depends on A.
Spark depends on Guava 14.x. My database classes depend on Guava 28.x.
I need to be able to use Guava 28.x in my database module, and declare that module as a project dependency in the Spark module.
Shading (and relocating) Guava in module A is easy enough:
shadowJar {
configurations = [project.configurations.shadow] // this was done to prevent ALL of A's dependencies from being shaded
relocate 'com.google.common', 'shaded.com.google.common'
}
dependencies {
shadow 'com.google.guava:guava:28.1-jre'
}
But, when I declare module A as a dependency in B, such as:
dependencies {
implementation project(':A')
}
The JAR that ends up on B's runtimeClasspath
is the unshaded JAR of A.
When I specify the shaded JAR, such as:
dependencies {
implementation project( path: ':A', configuration: 'shadow' )
}
None of A's transitive dependencies are available on B's runtimeClasspath
.
My goal is to shade and relocate only Guava in module A, to minimize JAR size and build time. I then need that shaded JAR as well as A's transitive dependencies available on B's runtimeClasspath
.
A somewhat-unsatisfying solution is to just declare in B the transitive dependencies I need from A. Because the set of dependencies is relatively small, this might be the best approach for this project; but I'd prefer something more elegant.
Maybe my reliance on transitivity is fraught? I've enjoyed doing so because it keeps the
dependencies
terse throughout the modules of this project, but it may be more trouble than it's worth.