why is transitive dependency not included my final war?

513 views Asked by At

Somewhat similar question is posted here. But no answers there.

I have multi-module maven project

when I run mvn dependency:tree, I see the following

[INFO] ------------------------------------------------------------------------
[INFO] Building Service 2.2.22-SNAPSHOT
[INFO] ------------------------------------------------------------------------

[INFO] +- org.apache.httpcomponents:httpclient:jar:4.3.2:compile
[INFO] |  \- commons-codec:commons-codec:jar:1.6:compile

[INFO] ------------------------------------------------------------------------
[INFO] Building common 2.2.22-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]  +- com.mycompany.project:jar:2.1.115:compile
           +- commons-httpclient:commons-httpclient:jar:3.1:compile
[INFO] |  |  \- commons-codec:commons-codec:jar:1.2:compile

No other configuration to exclude any library is done in pom.xml. In my final war/WEB-INF/lib,

I see commons-codec-1.6.jar, commons-httpclient-3.1.jar, httpclient-4.3.2.jar. But I do not see commons-codec-1.2.jar. why is that?

1

There are 1 answers

0
Mads Hansen On

Instead of including both commons-codec jars, which can lead to conflicts and issues, Maven's dependency mediation selected commons-codec-1.6.jar

  • Dependency mediation - this determines what version of a dependency will be used when multiple versions of an artifact are encountered. Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, until Maven 2.0.8 it was not defined which one would win, but since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.
  • "nearest definition" means that the version used will be the closest one to your project in the tree of dependencies, eg. if dependencies for A, B, and C are defined as A -> B -> C -> D 2.0 and A -> E -> D 1.0, then D 1.0 will be used when building A because the path from A to D through E is shorter. You could explicitly add a dependency to D 2.0 in A to force the use of D 2.0