Does child pom inherit plugins from parent pom - maven

In a multi module maven project, does a child pom inherits plugins defined in parent pom?
Maven documentation around the plugin inheritance is a bit confusing to me. According to the documentation
If your POM declares a parent, it inherits plugin configuration from
either the build/plugins or pluginManagement sections of the parent.
So I'm assuming only the configuration will be inherited in case if the child has the same plugin defined under <build><plugins> section. If child does not have the plugin then it's not inherited from the parent.
Can someone please confirm if this is the correct understanding, or I'm missing anything here.

You inherit everything, so your understanding is incorrect.

Related

Maven parent POM vs BOM dependency management

Let's say I have a maven parent POM root which defines foo:bar:1.0.0 in dependency management. I have another parent POM parent which uses root as parent (just to add another layer to the example). Lastly I have a bill of materials bom which uses root as its parent but redefines foo:bar:2.0.0 in its dependency management.
In my project app I inherit from parent and then I import the BOM in the dependency management section of app
root (foo:bar:1.0.0) <- parent <- app+bom
^
|
bom (foo:bar:2.0.0)
Which dependency management section wins? Which version of foo:bar do I get?
I know that if I were to directly include foo:bar in the dependency management section of app, it would override that inherited from the parent. But is importing a BOM in the dependency management section equivalent to directly including it in the dependency management section, and sufficient to override that of the parent? Or does the inherited foo:bar from the parent's dependency management take precedence?
According to the maven precedence rules, the version from the root will win and therefore you will get foo:bar:1.0.0, which you will be able to see if you look at the effective POM. I think that this makes a BOM project less effective since you cannot use it to override the version from the parent and have to declare the version in the app or in the parent.
The Precedence
So, there are multiple ways of deciding the versions,
which means there is an order of precedence.
Versions provided in the direct declaration in POM take the highest precedence.
Version provided in parent pom takes second precedence.
Version from imported pom takes third place
Lastly, whatever we get from dependency mediation

Do I need to have a Parent declaration in my POM.xml?

I've declared my project as a pom.xml to define the parent, and it triggers a reactor build of all the included modules. Everything builds fine and works as expected. It builds in the right order, all the tests run correctly, and I get my expected output.
One of the projects is a shared library. I don't want to add a <parent> declaration here, so I didn't. It all still works.
My Question: do I need to bother adding a parent project declaration in any of my sub-projects? What are the pros and cons of having a two-way relationship between the projects? If I don't add the declarations, am I going to make it harder later when something stops working?
Rephrased into a single question: why bother with <parent> configuration in module pom.xml files?
Your question is related to the difference between Project Inheritance vs. Project Aggregation. The <parent> reference defines the inheritance relationship. The <modules> section in the parent pom.xml defines the aggregation. They are different.
If you do not have the <parent> configuration in the module pom.xml, it will not inherit the parent pom.xml configuration. So let's say you define the version of a dependency in the parent pom in the <dependencyManagement> section, the module pom.xml without parent reference will not inherit that. Or if all your child modules need to use a common library, you can define the dependency in the parent pom.xml. However, the module pom.xml without the parent reference will not inherit that dependency either.
For details, please check out Project Inheritance vs Project Aggregation
It depends on how you configure your build. If you have a correctly configured parent pom, basic information like version and groupid can be shared between your projects.
You can define the project wide configuration information that should be shared in all the modules in the project. For example:
<modelVersion>4.0.0</modelVersion>
<groupId>groupd.id</groupId>
<artifactId>artifact.id</artifactId>
<packaging>pom</packaging>
<version>version</version>
With that in place, you do not have duplicate that information in the module projects. The same information can be referenced like so:
<parent>
<groupId>group.id</groupId>
<artifactId>artifact.id</artifactId>
<version>version</version>
</parent>
Remember that the parent pom can be used to shared more information than specified above. You can do dependency management, plugin management and even define re-usable profiles.

Possible to make Maven POM Element Not Inheritable?

I have a parent pom which defines a number of plugins and dependencies I want my child poms to inherit. However, we use the scm element as part of our release builds and I would like to add the parent's scm to the pom but it not be inherited by any children pom (in case the child forgets to define it and uses the parent's). Is there a way to set an element to be not inheritable?
I don't think so.
But could you make it use a property that ends up with different values in the parent pom and the dependent pom such that it will fail in the child if they don't have their own <scm> tag? Use <profile> to define the property differently in the parent and child.
Sometimes that works.
The reason it works on occasion is that profiles are not inherited by the child but if the profile in the parent sets a property, that property is inherited by the child.
So, sometimes you can use that "feature" to accomplish what you are doing. If you activate a profile in the parent and the <scm> section is in the profile, it won't be inherited by the child.
Another possible solution is for you to use the permissions on the version control system. The user credentials that allow checkin in the child projects could, in some cases, NOT be given permission to checkin in the parent. If the child project doesn't declare their own <scm> then they won't have permission to fool with the part of the repo in the parent's <scm> section.

How can I efficiently declare provided scope dependencies in maven multi-module builds?

I have a maven multi-module pom which builds a war. I want to declare a provided scope dependecy on jsp-api in the parent pom. Maven docs suggest that dependencies declared as provided are not transitive, so:
Do I therefore need to go through all the sub-module poms and declare a provided dependency? There are ~40 modules in the project and it's not immediately clear which will need the dependency, so this seems like quite alot of effort to achieve not very much and I am lazy. How are you handling this situation in your projects?
--Edit--
So for others reference this was happening because the parent pom was defining all dependencies in a dependencyManagment section. I'd not come across this before but it helps with cutting down duplication of complex dependencies with excludes or other non-trivial attributes. It also overrides the inheritance mechanism. As I understand it then, a good rule of thumb is to only use it to solve a problem don't just chuck all your dependencies in there as the author of this pom had done. Perhaps a suitable maven expert could confirm this.
Even though provided scope dependencies are not transitive they may be inherited. That is to say, if you have module A with a provided scope dependency, and module B has a dependency on A, module B will not implicitly have the provided scope dependency. However, I believe that if module C has module A as a parent pom, it should inherit that dependency as normal.
You can verify this behavior yourself by running mvn help:effective-pom on one of the child poms, the effective-pom goal should give you a fully resolved view of the pom you run it on, taking into account inheritance, equivalent to what maven will actually use when it runs. If the <dependency> shows up there (as it seems to in my experiments) you should be fine specifying the dependency only in the parent pom.

Maven include another pom for plugin configuration

is there a way to include another pom or information in a maven pom ?
I have several poms which are basically not related or have different parent poms. Nevertheless for packaging it is required to have a Manifest identical to all projects.
So currently I have in a pom:
<plugin>
<artifactId>maven-assembly-plugin>
<!--- .... -->
<archive>
<manifestEntries>
<build-date>....</build-date>
<build-nr>.....</build-nr>
etc etc
I would like to avoid to paste this configuration to all severall poms.
So how can I share the configuration of a plugin without inheritance ?
Thanks
One way to do this is using pluginManagement section. plugin configurations can be defined in this section in a parent pom and will be available to inherited poms to be used as is or overridden.
Here is the relevant maven documentation. In your specific case, you would need to organize your projects/poms suitably.
The only correct answer is to use inheritance. Have an inherited ancestor with this configuration in it. Since you have existing parent POMs, these must inherit from this new parent. If this isn't possible then rethink the hierarchy of your Maven projects, or else you'll have to copy and paste the same configuration into each file and add a comment indicating the section must not be modified / must be maintained consistently with [insert list of projects here].
TLDR; Inheritance is designed specifically to resolve situations such as yours. If you can't use it then don't try to hack around it - either restructure your POMs or copy and paste!

Resources