The Bill of Materials in Maven
The Bill of Materials in Maven
Learn more about BOM — one of the few ways Spring helps us forget about transitive dependency issues.
Join the DZone community and get the full member experience.Join For Free
This blog was first published at Knoldus Blogs.
Lately, while working with Spring WebFlux, I came across this really helpful concept called the bill of materials, also known as BOM, a concept not really limited to Spring at all. BOM is one of the few ways Spring helps us forget about issues related to transitive dependencies and focus solely on our project requirements.
So when we generally create a large scale project with dozens or hundreds of dependencies, chances are multiple of them use something common internally by transitive dependencies. So, let's say we have a dependency called “common-3.0.0.RELEASE,” which is used by our logging artifact and “common-2.9.0.Release” used by our testing framework. In such a case, we have a conflict. We need to ensure we get a working version so that both the artifacts can work together in synergy.
There’s a way Maven solves this problem for us. It uses the concept of dependency mediation. It works on something known as a path to the dependency. Whoever has the shortest path to the project is picked over the other. So, let's say, in our case, the chain is something like log4j —> commons —>2.9.0.Release and JUnit —> unit-tests —> common.3.0.0.Release, maven selects commons 2.9 since it has a shorter path to this POM.
But why rely on some external method when we can control stuff right? We can always use a version we’re hoping to use even transitively by specifying it in the POM. Sure, but this would clutter our POM because how many are we going to mention? Or we could do one better. We can let dependency management take control.
Maven lets us define the versions of our dependencies or transitive dependencies in a separate POM. It is in this POM that we declare the versions and scope of the dependencies. Hence, we get a centralized place to mention all the dependency details.
Let’s create a sample bill of materials POM file.
As can be seen, the bill of materials is a perfectly normal POM file where we can include our dependency information.
How to Use It?
Now we understand that there’s a file that contains all information regarding the versions of any dependency that we may want to be a part of our project. The next thing is to include this file in our original POM.
One way to do this is the way Spring does it, by inheriting it like a parent project. All we need to do to inherit is to provide the parent information in the parent tags.
Though this is how Spring works, we can not inherit from more than one parent POM. So, in case you wish to inherit from more than one, we pass the credentials in our dependencies.
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
In case of conflict when inheriting multiple POMs, the dependency declared earlier in order takes precedence.
So now, you can understand why things magically auto-configure in Spring POMs, what a BOM is, and what to do in case there’s any custom operation you wish to perform. Thanks for reading the blog and please let me know your thoughts in the comments.
Published at DZone with permission of Ayush Prashar , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.