Maven dependency version range

Number945 :

I want to understand the difference between [3.8.2] vs 3.8.2 when mentioned for our dependency's version.

From here ,

When declaring a "normal" version such as 3.8.2 for Junit, internally this is represented as "allow anything, but prefer 3.8.2." This means that when a conflict is detected, Maven is allowed to use the conflict algorithms to choose the best version. If you specify [3.8.2], it means that only 3.8.2 will be used and nothing else. If somewhere else there is a dependency that specifies [3.8.1], you would get a build failure telling you of the conflict. We point this out to make you aware of the option, but use it sparingly and only when really needed. The preferred way to resolve this is via dependencyManagement.

But I feel something is wrong here.

if I write <version>3.8.2</version> for our dependency and that version artifact is not present in our maven repo, then it is not picking anything else. Build simply fails. So, why above they are saying - "allow anything, but prefer 3.8.2."

Also, they say - This means that when a conflict is detected,.... I am not able to understand this. What possible can be a conflict that does not arise for 3.8.2 but arises for [3.8.2] ?

JF Meier :

The whole thing works as follows:

Step 1: Maven builds a dependency tree for your project, including your direct dependencies, their dependencies, the dependencies of your dependencies and so on.

Step 2: Now Maven makes a list of all nodes. If it encounters a dependency in just one version (say 3.8.2 or [3.8.2]) it will pick just that version.

Step 3: If Maven finds more than one version, the magic begins.

  • If all versions are versions without brackets (like 3.8.2), it picks the "nearest" version as mentioned in dependency mediation principle.

  • If you have some (or all are) version ranges (like [1.0.0,2.0.0]) or fixed versions (like [1.0.0]), then first it finds the intersection of all ranges/concrete version (Note that it does not consider versions without brackets here for finding this intersection).

  • If this intersection is found null, build fails. If it is not null, then it proceeds further by chooses the "nearest" version/concrete version/version range.

  • If by nearest definition, we get a version range/concrete version, then maven selects the most recent available version in resultant intersection of version range found.

  • If by nearest definition, we get a version (not concrete version) , then maven checks if that version is present in resultant intersection of version range found. If yes, this version is selected. If not, then maven selects the most recent available version in resultant intersection of version range (and does not fail the build).

The quote "allow anything, but prefer 3.8.2" is at best misleading. Maven does not try to make up for missing dependencies in the repository, it just "mediates" versions if more than one version is found in the dependency tree.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=357921&siteId=1