Michał Borek

Tech blog

BOM generation of all submodules in Gradle.

When you create a common use library, which consists of many sub modules (artifacts), you probably would like to generate a Maven BOM (Bill of Material) file, so that you can avoid version declaration duplication.

Doing it in Maven is quite straightforward, but in Gradle (as of today) it is not well documented and many Gradle based complex projects lack BOM file.

Fortunately Spring IO Dependency Management plugin helps us with doing that.

Let’s start with a simple Gradle based project with two submodules (client and server):

Bom

First you need to apply maven-publish and io.spring.dependency-management plugins. The first one will be responsible for BOM generation and the latter one will add a dependencyManagement DSL to define versions of your modules.

1
2
3
4
    plugins {
        id 'maven-publish'
        id 'io.spring.dependency-management' version '1.0.5.RELEASE'
    }

To simplify project configuration, all projects have following configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    allprojects {
        repositories {
            mavenCentral()
        }
        apply plugin: 'java'
        group 'pl.greenpath'
        version '1.0-SNAPSHOT'
        sourceCompatibility = 1.8
        dependencies {
            testCompile group: 'junit', name: 'junit', version: '4.12'
        }
    }

Then you need to declare versions of modules in dependencyMangement section. We will add all gradle modules (subprojects) so that we are not forced to manually add each new module.

1
2
3
4
5
6
7
    dependencyManagement {
        dependencies {
            rootProject.subprojects.each {
                dependency(group: it.group, name: it.name, version: it.version)
            }
        }
    }

Then, all we need to do is to declare maven BOM generation using maven-publish plugin’s DSL. We need to define mavenBom empty publication (without additional artifacts defined).

1
2
3
4
5
6
    publishing {
        publications {
            mavenBom(MavenPublication) {
            }
        }
    }

Now, everything is done and we can test it:

1
./gradlew publishToMavenLocal

In effect we have following BOM artifact generated:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <modelVersion>4.0.0</modelVersion>
      <groupId>pl.greenpath</groupId>
      <artifactId>bom-demo</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>pom</packaging>
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>pl.greenpath</groupId>
            <artifactId>server</artifactId>
            <version>1.0-SNAPSHOT</version>
          </dependency>
          <dependency>
            <groupId>pl.greenpath</groupId>
            <artifactId>client</artifactId>
            <version>1.0-SNAPSHOT</version>
          </dependency>
        </dependencies>
      </dependencyManagement>
    </project>

I hope this going to help you create useful BOM files. Having BOM’s it is easier to keep track of project’s dependencies and to enforce consistent versioning across applications you create.


Share