My project and my parent pom both have a dependency management section. These sections both have direct entries and "imports" of boms (i.e. poms that purely consist of dependecyManagement and are imported). Now I try to figure out the evaluation order. My best guess:
parent pom imports
child pom imports
parent pom direct dependencyManagement entries
child pom direct dependencyManagement entries
This means that later elements overwrite earlier elements. Is this correct? If so, can I change this behaviour so that the child elements always overwrite the parent elements?
Following the ticket
issues.apache.org/jira/browse/MNG-5971
it is indeed true that direct management entries cannot be overwritten by imports in child projects. This behaviour should be altered in Maven 3.6.0, according to the statements in the ticket.
As Maven 3.6.0 is distant future, I have to work around this problem. I will probably avoid direct management entries in the parent pom by constructing an auxiliary bom.
Related
We have a Maven multi-module project with some 30 child projects/module in it.
All child projects where using those two dependencies. (This is just to put something concrete in the example)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra-reactive</artifactId>
</dependency>
Hence, we refactored and put those two dependencies to the parent POM. The snippet from above is now in the parent level. All child projects could still benefits from it, and have to only maintain the version in one place, all very happy.
We now have a 31st project which fits the business use cases and fits inside this multi module project, we believe it makes sense to have it under this same parent POM.
However, this 31st project does not need one particular dependency from the Parent POM. (In this case the Cassandra dependency, but the question is about how to exclude something from the parent)
Having this 31st project part of this multi module, he also takes this dependency (Cassandra) from the parent. How to tell this child project to exclude this dependency from the parent?
I do not want to extract this project entirely and have it separated from the multi module.
I tried putting an exclusion in ALL dependencies, but it is still there. Like in all dependencies of my child pom, I write this:
<dependency>
<groupId>some.group</groupId>
<artifactId>some.artifact</artifactId>
<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra-reactive</artifactId>
</exclusion>
</exclusions>
</dependency>
I even tried doing the crazy refactor of moving the dependency away from the parent back to all children, and did 30 copy paste to the child, with my 31st project not having it. This works, but I believe there is something smarter than that.
How to exclude one particular dependency from the Parent POM please?
The way I normally do this is by using a multi-level hierarchy of poms.
This means that instead of a single parent-pom with just one row of non-parent poms underneath it, I have an entire tree of parent poms consisting of a root-parent-pom with several levels of intermediate-parent-poms as its children, ending with the non-parent-poms as the leaves of the tree.
By adding intermediate parent-poms you can have the root parent only provide the dependencies that are truly used by all children, while intermediate poms can provide additional dependencies that are only used by their children but not by children of their siblings.
So, in your case, your root parent pom would declare all dependencies except cassandra, and it would have two children: your casandraless project, and your existing parent pom which would now become an intermediate parent pom and it would only declare the cassandra dependency. So, the children of the intermediate parent pom would inherit all the dependencies except cassandra from the root, and then cassandra from the intermediate parent pom.
I have tried this, it works very well.
It is true that there may theoretically exist situations that cannot be covered, because parent poms can only form a tree, and a tree is not a graph, but in practice I never came across a situation where I wanted to arrange my dependencies in such a way that this mechanism could not cover.
As an example, take a look at my public home projects, which I have rolled all together into one repository for the sake of more easily managing them:
https://github.com/mikenakis/Public
https://github.com/mikenakis/Public/blob/master/pom.xml is the root pom.
https://github.com/mikenakis/Public/blob/master/testana/pom.xml is an intermediate parent pom,
https://github.com/mikenakis/Public/blob/master/testana/testana-console/pom.xml is a child pom. (A leaf.)
Now, in my projects it just so happens that I only declare dependencies in the leaf poms, because my projects do not really depend on many external libraries. But I could be declaring dependencies in the root pom and in the intermediate parent poms if I wanted to, and their children would be inheriting them.
I have a Parent POM that has a Child mentioned in its <dependencies> section. Is this allowed?
Please note this is not the <dependencyManagement> section but the <dependencies> section itself, so that any child inheriting from this parent will have all these dependencies available for them by default.
However, these children that are part of the <dependencies> section of the parent, have to somehow exclude themselves from the parent when they are built?, Is this possible?
Currently, the child builds are failing saying that they are referencing themselves from the dependencies section of the parent.
The reason why we have these children as part of the parent's dependencies section is because these dependencies have to be available by default for the other children of the parent implicitly.
Any suggestions / help is much appreciated!
You cannot use modules as dependencies in the parent POM.
The modules need to declare their dependencies to other modules themselves.
Given a pom.xml file, what would be a reliable way to determine the GAV of the parent?
At the moment, I am parsing the XML, but this means that terms like ${some.number} need to be resolved by hand.
Is there a Maven goal or an Aether method that determines the parent pom for a given pom.xml?
I am a newbie of Maven, currently reading Hadoop source code, and found something interesting in some pom.xml files:
Some of the dependency node do not contain version node at all.
Question: why is it like this?
for instance, this pom.xml.
Because specific version of dependency in parent pom.xml file
https://github.com/apache/hadoop/blob/trunk/pom.xml
Reference: https://maven.apache.org/guides/introduction/introduction-to-the-pom.html
As I commented at first, a pom file can have a parent (via inheritance) and such a parent may provide some governance and harmonization across all of its children. A classic case is to provide versioning for certain dependencies via a dependencyManagement section.
is used by POMs to help manage dependency information across all of its children. If the my-parent project uses dependencyManagement to define a dependency on junit:junit:4.0, then POMs inheriting from this one can set their dependency giving the groupId=junit and artifactId=junit only, then Maven will fill in the version set by the parent. The benefits of this method are obvious. Dependency details can be set in one central location, which will propagate to all inheriting POMs.
The mentioned pom has indeed a parent pom:
<parent>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-project-dist</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../../hadoop-project-dist</relativePath>
</parent>
Which in chain has another parent pom file which defines several dependencies as part of its dependencies management section.
If you really want to check the effective (merged) pom your build is using, you could run:
mvn help:effective-pom -Doutput=effective-pom.xml
And the maven-help-plugin will produce an additional pom as specified by the command above, merging the current pom file and all of its anchestors.
In Maven you can inherit from parents folder in order to merge or inherit some properties. This can be the version of the modules. Usually you have a "super" POM in the root folder of your project and you put there all the commons dependencies in order to controll them in an easier way. I.e. If you must change one module version, you only need to change in the "super" POM and not in each POM inside each subfolder that need it. If you need more information about POM inheritance the documentation has a couple of useful examples.
https://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Project_Inheritance
I am using mvn archetype:create-from-project within a manually created project
This project has both inherited and aggregated modules.
However when creating a new project based on this fresh archetype, the aggregated module pom file always finds itself injected with <parent>..</parent> attribute thus inheriting rather than being aggregated, which screws up the build order.
How can I prevent this aggregated module to be injected with <parent> tag?
It's actually not possible.
There's an open request for it on their JIRA from November 2011:
As mentioned in ARCHETYPE-110, the current implementation overwrites parent information if there are no existing parent definition inside the body of the pom.xml. So if we don't want such declaration we haven't no alternatives.
Source: https://jira.codehaus.org/browse/ARCHETYPE-393