Dependency Management in AEM project POMs - maven

In AEM project poms I have noticed that dependency name and versions are defined in the parent pom and it is not necessary to specify a version in child poms, as the version is managed at the Parent pom. And child poms only have dependencies defined. So, I am not clear on following.
1.If we already have dependencies defined in the parent pom with version no, then why do we need to define the same dependency back in child pom.xml (core/pom.xml in case of AEM).

In Maven there is a difference between <dependencies> and <dependencyManagement>. Only the former really adds dependencies to your project, while the latter only defines the preferred version numbers (and scopes).

Related

Should you include those dependencies in your pom that are already the dependencies of some of your dependencies?

Say there are two dependencies you need: A and B. And at the same time A is already a dependency of B. So do you still want/need to add A along with B as dependencies in your pom?
I believe this may be needed when A and B are external libraries where the version of A needed may be different than the version of A that B is depending on.
But how about when both your module and A and B are modules in the same project? i.e. knowing their versions are all going to be in sync.
If your module uses APIs from B it's best practice to add it explicitly to your pom, even though it's not strictly necessary. If you upgrade A, it could well be that it doesn't use B anymore and then you'll get a build failure without any changes to your module code.
Regarding versions, you should manage those with dependencyManagement in a parent pom. You can then skip the version for the managed dependencies in the child poms. The version in the dependencyManagement overrides the version in transitive dependencies, ensuring you use the same version everywhere.
If all modules are in the same project, they should also share the same project version. Typically, this will be a snapshot version, e.g. 1-SNAPSHOT
Each module will use something like:
<project>
<artifactId>A</artifactId>
<version>1-SNAPSHOT</version>
And refer to A and B like this in other modules:
<dependency>
<groupId>com.yourcompany</groupId>
<artifactId>A</artifactId>
<version>${project.version}</version>
</dependency>
To set a non-SNAPSHOT version before you build a release, you can for example use the maven-dependency-plugin's versions:set goal.

POM references a dependency and a parent the same way. How we choose what is what?

I found that syntax of parent and dependency references in POM are practically the same:
<parent>
<groupId>com.topdesk</groupId>
<artifactId>tis-parent</artifactId>
<version>3.4</version>
</parent>
Dependency has the same inner content. Why we choose to put something as parent instead of using dependency?
These are different concepts. Referencing a parent makes Maven look for a pom from which it inherits (using all the plugin definitions, profiles, declared dependencyManagement etc.), i.e. the parent and your pom are put together as one and executed.
Using a dependency means that Maven looks for a jar (unless you explicitly tell it to look for a pom, which essentially means that it adds all dependencies from that pom as transitive dependencies). This jar is put on the classpath (together with its dependency tree).

How to Include a BOM(bill of material) as a child of the parent pom

According to Maven documentation, BOM should be the parent of the parent-project.
However, I am following what Resteasy does by including the BOM as the child pom of the parent-project.
Since the parent pom needs to have all the dependencies declared with version, I want to figure out a way such that I am able to remove all of the dependencies from my parent-pom and just have it in my BOM

Maven: Import pom properties from different pom

I would like to import properties from a project X pom file into my project Y pom such as library versions. I do not want to make the project X my project's parent.
I have tried to include project Xs pom in the dependency management section as an import.
<dependency>
<groupId>abc</groupId>
<artifactId>def</artifactId>
<version>1.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Please advise.
Thanks.
I think, today, the answer is NO. You can't read properties from external dependency without inheritance.
However a hack can be done with the codehaus Properties Maven Plugin. In fact, it can load maven properties from an external file. It can even use classpath: URLs to load files from. So you might try to load those from another dependency (which should have an appropriate scope since you probably do not want that dependency's JAR to hang around at runtime).
The usual approach to share dependency versions without using parent POMs are BOMs.
These are separate projects that only contain a pom.xml which consists of <dependencyManagement>. This can then be imported in several other projects with <scope>import</scope>.
These other projects then import the dependencyManagement inside the BOM.
Basically, you need to create a parent pom which is imported by both projects.
The parent has a <dependencyManagement> section which lists groupId, artifactId and version
The child pom's only need to list groupId and artifactId since the version is inherited from the parent's <dependencyManagement> section
eg:
root/pom.xml - Builds all modules, a simple pom with a `<modules>` section which includes parent, project1 and project2
root/parent/pom.xml - This has a `<dependencyManagement>` section
root/project1/pom.xml - parent=../parent/pom.xml
root/project2/pom.xml - parent=../parent/pom.xml
More info here

maven: parent-version

I don't understand what is the parent version and for what it should be good?
We use svn in our team and when I did update for the project the last time I notcied that the parent version is changed:
local pom.xml
<parent>
<artifactId>foo</artifactId>
<groupId>bar</groupId>
<version>0.42-SNAPSHOT</version>
</parent>
svn pom.xml
<parent>
<artifactId>foo</artifactId>
<groupId>bar</groupId>
<version>0.45-SNAPSHOT</version>
</parent>
When does parent version change and for what it should be good?
A parent POM contain settings that apply to all child modules. This may include declaring plugin settings or choosing dependency versions.
A parent POM is no different to any other Maven artifact. It can change and when it does the version number must increment. Typically you want to always be using the latest available version of your parent.
You can use the Maven versions plugin to help manage versions, including forcing an update to the latest available parent version.
Parent pom and child pom come into picture if you have a multi-module project. For example like the below
/myapp
|- pom.xml --> parent pom
|+ module1/
| - pom.xml --> child pom
| - src/
|- module2/
There can be several such hierarchies. There are 2 ways to define this inheritance
Add a xml block in parent pom to tell it which are the dependent modules. OR
Add a xml block in a module to tell whose is it's parent. (This is your case)
This means that, the child pom is dependent on parent and will try to find the the concerned artifact with 0.45-SNAPSHOT version. This version has changed probably due to a newer build of parent has taken place replacing the version.

Resources