To BOM or not to BOM

Maven let’s you define the artifacts that you want to include in your Java based project. Whether you want to include the artifcts in your own build artifacts, or just want to have them available to compile against, you can decide what is applicable for your situation. In a Java EE / Jakarta EE / MicroProfile context, you will likely do the latter because of the nature of these platforms. I will explain later why this is such a good fit.

However, MicroProfile’s 2.2 release includes a BOM-style dependency for MicroProfile artifacts in addition to the conventional dependency that provides MicroProfile’s API’s for that specific version. You might wonder what the difference is and in which situation one of these options is to be used. In case you’re interested, read further and you should be able to choose the applicable option when the situation calls for it.

Dependency management (non-BOM-style)

First let’s look at the conventional, and far easiest way to get started with Java EE / Jakarta EE / MicroProfile using Maven. Below a snippet is shown that you should include in your pom.xml, and you are ready to start coding.

<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile</artifactId>
<version>2.2</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
</dependencies>

When you want to use an application server that is Java EE 8 compliant, you only have to include the javaee-api artifact dependency as shown in the snippet. However, if you choose an application server that also implements MicroProfile, you can add the microprofile artifact dependency in addition to the javaee-api artifact dependency in order to seamlessly use both in your enterprise application.

In the context of a Java EE 8 and optionally MicroProfile compliant application server, you want to have transparent access to all of the Java EE 8 and MicroProfile API artifacts because the application server provides the implementation. Due to the <scope>provided</scope> definition of the dependencies for javaee-api and microprofile artifacts, they provide you with exactly that because all of these API artifacts are defined in their <dependencies> sections.

Dependency management (BOM-style)

Now that we have a clear definition of what our “conventional” dependency management for using Java EE / Jakarta EE / MicroProfile looks like, let’s compare it with doing the same in BOM-style. BOM stands for BILL OF MATERIALS, which in the Maven context means that you have a list of artifact dependencies available, but not transparently. You explicitly cherry-pick which of these to use in your project by defining them as <dependencies> in your own pom.xml. This is exact opposite of transparently having access to every artifact as described in the non-BOM-style section.

So to switch to a BOM-style dependency, we can change our previous pom.xml snippet to the following:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile</artifactId>
<version>2.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

If you look closely, two things have changed. First, the microprofiledependency has moved to the <dependencyManagement> section, but the javaee-api dependency has not. The second thing to notice is that the microprofile dependency’s scope has changed to <scope>import</scope>.

So what does this exactly mean? Well, remember that in the non-Bom-style section, I mentioned that all the <dependencies> of an artifact defined with <scope>provided</scope> were transparently available in your project? With changing the microprofile dependency to <scope>import</scope>, we are no longer transparently accessing microprofile‘s <dependencies>, but microprofile‘s <dependencyManagement>. This effectively means that the microprofiledependency is making no artifiacts transparently available to our pom.xml, but only the associated versions! So if we now expand our snippet with an explicit dependency to microprofile‘s Health specification API for example, we will have access to that particular API, using the version that has been defined in microprofile‘s <dependencyManagement>.

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile</artifactId>
<version>2.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.health</groupId>
<artifactId>microprofile-health-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

One question that remains is why I haven’t moved our javaee-api to create a BOM-style dependency. Well this is simply because this artifact doesn’t define a <dependencyManagement> section in it’s pom.xml. For that reason it is just not possible to create a BOM-style for this specific javaee-api dependency because there would be nothing to “dependencyManage“. In case you will try anyway ;), it is perfectly valid to define the javaee-api as <scope>import</scope>, but this just doesn’t do anything.

Conclusion

BOM-style dependency management can be applicable for your situation, but in the context of a Java EE / Jakarta EE / MicroProfile application server, it makes little sense. However, the BOM-style could make sense when you are using a microservices framework that implements MicroProfile. In which case, you also want or need to right-size your application by defining a <dependency> on the artifacts that you explicitly want to in- or exclude in the build artifacts of your project.

When I have more information and experience on whether or not to use BOM-style dependency management in the Java EE / Jakarta EE / MicroProfile ecosystem, I will of course be happy to share it with you. In any case, I hope this concept now makes sense and that you now can decide for yourself when to apply it in your own projects.