What if I have two versions of the same dependency: one in parent pom, another in child pom? How does Maven resolve it — assuming no <dependencyManagement>
?
Please back it up with a doc quote, if possible.
<!-- parent pom -->
<dependency>
<groupId>com.example</groupId>
<artifactId>some-artifact</artifactId>
<version>1.1</version>
</dependency>
<!-- child pom -->
<dependency>
<groupId>com.example</groupId>
<artifactId>some-artifact</artifactId>
<version>1.0</version>
</dependency>
I found this in the Maven documentation
Dependency mediation - this determines what version of an artifact will be chosen when multiple versions are encountered as dependencies. Maven picks the "nearest definition". That is, it uses 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, the first declaration wins.
However, save for this brief mention
In general, all dependencies of those projects are used in your project, as are any that the project inherits from its parents, or from its dependencies, and so on.
it doesn't mention parent poms explicitly, so I'm not sure whether it describes my case as well.
In our project, we have a thing called common-lib
. It has a bunch of "common" types, some are in-house, some come from external libraries. It is declared as a dependency in a number of project poms. Sometimes, common-lib
declares the same dependencies as other projects that depend on it. It is not guaranteed the versions would be the same (although the convention is followed at the moment). I was wondering whether Maven specifies that behavior (as opposed to figuring it out with no strings attached).
I don't think you will find explicit documentation on this at the moment. As far as I understand, the following happens; When Maven builds the child project it will inherit the dependencies from it's parent.
Elements in the POM that are merged are the following:
- dependencies
- developers and contributors
- plugin lists (including reports)
- plugin executions with matching ids
- plugin configuration
- resources
It will first resolve the dependencies from the parent, after which it will merge the dependencies from the child. Effectively overwriting the dependency. This case there is no need to 'choose' a version as it is only one dependency.
This is different when we are talking about transitive dependencies that are added to the project through other dependencies. When we have our POM define 2 dependencies which both require dependency X with X having different versions, the first declaration wins.
Note that if two dependency versions are at the same depth in the dependency tree, the first declaration wins.
When you define the same dependency on the same level (effectively in the same POM) Maven 3 will allow this by merging the dependencies. If the versions differ because you are e.g. not using properties, you might got yourself a non-reproducible build (the result might differ theoretically each run depending on the implementation of Maven).
Good to note that for this final case Maven 4 will not even build and provide you with a build error.
I would however, in most cases, recommend using the dependencyManagement.