As you use a number of dependencies, each of them in turn may also include further dependencies. A situation may come when there are multiple versions of the same dependencies in the project. This can often lead to errors.
To understand this, we need to have a fairly complex project that has several transitive dependencies. You can look at one such project at https://github.com/selendroid/demoproject-selendroid.
Clone the repository on your system. Now, we are ready to see how complex dependencies can get.
Use the following steps to avoid dependency hell:
mvn dependency:tree -Dverbose
As you can see, in the course of identifying the dependencies to be used in the project, Maven does a dependency analysis. This reveals two things:
Maven resolves this by supporting the nearest definition, which means that it will use the version of the dependency closest to your project in the tree of dependencies.
This means it will not necessarily take either the latest or the oldest version. It will go by the version that it finds first in the order of dependencies.
Where the project fails to work due to the incorrect version being used, the correct way to resolve is to explicitly define the desired version of the dependency in your pom file. By the previous strategy, this being the nearest definition will get precedence over any other versions defined in any other dependency.
Maven provides another way to handle the preceding scenario, namely, by using the dependencyManagement
element.
This allows us to directly specify the versions of artifacts to be used when they are encountered in transitive dependencies or in dependencies where no version has been specified. In the example in the preceding section, the guava
dependency was directly added to demoproject-selendroid
, even though it was not directly used by the project. Instead, demoproject-selendroid
can include guava
as a dependency in its dependencyManagement
section and directly control which version of guava
is used when, or if, it is ever referenced.
There is no magic bullet to prevent dependency hell. Even if you manually manage the version of a library that gets included in your project by the preceding mechanism, it does not mean that other transitive dependencies, which depend on a different version of the same library, will suddenly become binary compatible with the managed version.
3.143.0.85