Use BOMs whenever available

A BOM is a Bill of Materials that in the Java ecosystem is typically represented as a specialized Maven POM file. It includes details of many libraries, including a specific version number. When a project decides to include a BOM dependency, the project is relieved of the requirement of specifying a dependency version for any library that is specified within the BOM file. In fact, it is encouraged that when a BOM dependency is taken, any explicit dependency versions specified in your projects configuration file (be it a Maven pom.xml, a Gradle build.gradle, or something else) be removed, so that version decisions are left up to the BOM.

It is really important to note that including a BOM dependency does not imply that all of the dependencies listed within the BOM are automatically dependencies of the project depending on the BOM. In fact, including a BOM dependency results in zero immediate changes to your project, except that there is a new place to look for dependency versions when a dependency is specified without any versions.

Many popular projects have BOMs that developers can choose to use. For example, you can see details of BOMs for some popular projects below:

The benefits of BOMs

The immediate question to ask is: why use BOMs? The answer is simply that the people publishing a BOM have likely taken some amount of effort to ensure that the dependencies listed within the BOM work together. For example, in the Azure SDK for Java, the dependencies listed in the BOM are tested (and proven through rigorous tooling) to ensure that the transitive closure of all dependencies is as minimal as possible (which is just a fancy way of saying we really try our hardest to avoid dependency conflicts for you).

Once you move to using a BOM, your burden of keeping dependencies up to date is lessened due to the fact that you have far fewer dependencies whose dependency is explicitly expressed. Now, your burden is to upgrade BOM versions at times that are appropriate for you.

How to use a BOM

Maven

In Maven, a BOM is included within the dependencyManagement section of a Maven POM file, rather than the standard dependency section for normal dependencies. For example, including the Azure SDK BOM would be achieved as shown below (be sure to check Maven for the latest version):

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.azure</groupId>
      <artifactId>azure-sdk-bom</artifactId>
      <version>1.0.3</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

Once a BOM has been specified (and note, you can include more than one BOM in a project), you can remove the dependency numbers from any dependency listed in the BOM. For example, a dependency on azure-storage-blob should appear as the following:

<dependencies>
  <dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-storage-blob</artifactId>
  </dependency>
</dependencies>

You can read more about importing BOMs in a Maven project in the Maven documentation.

Gradle

Gradle provides support for importing Maven BOM files, but unlike in Maven, Gradle BOMs are included via a regular dependency declaration on the BOM, for example:

dependencies {
    // import a BOM
    implementation platform('com.azure:azure-sdk-bom:1.0.3')

    // define dependencies without versions
    implementation 'com.azure:azure-storage-blob'
}

You can read more about importing BOMs in a Gradle project in the Gradle documentation.