## What is a POM?
A Project Object Model or POM is an XML file that contains project configuration used by Maven to build it.
The minimal POM should include tags that describe project: project root, modelVersion, groupId, artifactId and version. These last three values form the project artifact name, in format **<groupId>:<artifactId>:<version>**.
One of the configurations that can be included in the POM is the project dependencies that are based on artifacts.
In our projects we are using them by including **<dependency></dependency>** with all parts of the artifact name, in POM's section **<dependencies></dependencies>**.
## Why we should organize dependencies?
Dependencies can be included in the project in many different ways.
Because all approaches can be combined with each other we can simply lose control of it and finish with mixed artifacts versions, often not compatible with each other.
This is not a situation we want to find ourselves in when some features stop working because of not compatible classes, etc.
In next sections we will describe better ways how to organize this chaos.
## Managing dependencies
POMs can be arranged in structures when one POM can inherit configuration from his parent.
One parent POM can have many children POMs. Each child should have his parent declared or parent POM should include list of children.
Any child can also have his own children, and each of the children will be inheriting configuration not only from the direct parent but also from his parent's parent, etc.
Because we have special section **<dependencyManagement></dependencyManagement>**, this inherits mechanism can be used to manage our dependencies.
All we need to do is to declare this section in our top parent POM and specify all dependencies that we want to use in whole project, ex.:
and in our sub POMs we declare only that we want to use this dependency:
without specifying version or scope. It allows us to easily handle between artifacts versions, because we need to check only one file to change it for all places.
### External parent POM
Instead of creating own parent POM with **dependecyManagement** section we can use existing one.
Good example here is Spring Boot. To use it simply declare parent:
In this way beside dependencies we are also getting shared plugins configuration.
Sure, we can do it by ourselves by using **pluginManagement** in similar way how we used **dependencyManagement**, but
instead we can use ready solution.
BOM is a shortcut from Bill Of Materials.
It's a special kind of POM and another way how to configure dependencies, ie. when we cannot use parent POMs.
To add it to your project you can set is as parent POM, but also you can import it in **dependencyManagement** section:
Now, if you know how to manage your dependencies let's see how to clean your project.
If you are using similar dependencies in same version, like:
you can use
and declare version in properties:
This approach will allow you not to forget to change any version, when upgrading.
### Dependencies duplicates
If you have many POMs in your project is easy to got duplicate declarations.
To quickly find duplicates you can use **maven-enforcer-plugin**. Just add:
in your project and after each project build you will see warnings if you have duplicates:
[WARNING] Some problems were encountered while building the effective model for pl.j-labs:spring-boot-demo:jar:1.0.0-SNAPSHOT
[WARNING] 'dependencyManagement.dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique: org.springframework.boot:spring-boot-starter:jar -> duplicate declaration of version 2.2.2.RELEASE @ line 33, column 29
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
### Transitive dependencies
Another good example why to use **maven-enforcer-plugin** is to eliminate transitive dependencies from your project.
Declaring dependencies directly can be useful, because it simplifies detecting conflicts or makes us sure that we use exactly what we want.
To obtain list of dependencies not directly declared we should add another rule to our plugin configuration:
In this case build will fail when plugin will detect transitive dependencies:
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.BanTransitiveDependencies failed with message:
Rule 0: org.apache.maven.plugins.enforcer.BanTransitiveDependencies failed with message:
org.springframework.boot:spring-boot-starter-web:jar:2.2.2.RELEASE:compile has transitive dependencies:
In addition to the two functions I have described, this plugin has many more uses
Full functionality list can be found on his page.
Sometimes complications resulting from clutter in our POM files can be very painful.
A clean POM will not only avoid them but also speed up future application development.
[Apache Maven Project](http://maven.apache.org/ref/3.6.3/)
[Apache Maven Enforcer Plugin](http://maven.apache.org/enforcer/index.html)