Why are jackson library dependencies missing when used in sub project using gradle?

Viewed 820

I have a gradle project P which has module A and B. Module A has this jackson dependencies:

...
dependencies {
    ...
    compile 'com.fasterxml.jackson.core:jackson-core:2.12.0-rc1'
    compile 'com.fasterxml.jackson.core:jackson-annotations:2.12.0-rc1'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.12.0-rc1'
    compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.12.0-rc1'
    ...
}
...

and module B uses module A, and has no need for including this dependencies because jackson usage is encapsulated in module A. But when code executed from module B reaches a statement that invokes code from Module A using it, I get exception:

java.lang.NoClassDefFoundError: com/fasterxml/jackson/dataformat/xml/XmlMapper

If I add the same dependencies to Module's B gradle.build file, the code works. The question is, why would I include them if Module A does not use the library? Shouldn't dependencies in Module A be compiled, packaged, so that when Module A is used elsewhere, its code works (using its included dependencies such as jackson library as in this example)

1 Answers

Disclaimer: I don't know Gradle, but this sounds like a problem common to Maven and Gradle.

The fact that you can build the module, but not run the module, means that somewhere you are not bringing the transitive dependencies into the Spring Boot fat jar. Jackson doesn't do anything weird with metadata files, classloaders, etc. It plays well with others in a fat jar.

Given that you haven't shared much of your build files, the easiest way to figure out if something has excluded the Jackson XML module is to just run jar -xvf target/app.jar and inspect the output to see if it's in there.

If it's not, look for a Gradle equivalent of the Maven dependency plugin's dependency-tree target that will show you the whole transitive dependency tree. If it's being excluded you'll definitely see it missing from a dependency dump.

Related