Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import maven property used in bill of materials (bom)

We have a project layout with sub-modules and dependencies in bom files:

projectA
    bom           
    module1
    module2

The actual version numbers are defined as properties in the bom file, so for each dependency we have something like

    <properties>
        <guice-version>4.1.0</guice-version>
    </properties>

<dependencies>
    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>${guice-version}</version>
    </dependency>
</dependencies>

The top-level pom in projectA import the bom in the dependecyManagement section with

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>group</groupId>
            <artifactId>bom</artifactId>
            <version>1.0.0</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

This all works fine and we have centralized dependency definitions.

However, at one point during the build process we need to use the version of one of the dependencies. I was hoping that importing the bom in the dependencyManagement section would also import the properties into the top-level pom, but that is not the case. It is also not possible to make the bom a children of the top-level pom with a section because this creates a cyclic dependency between pom files.

I thought about putting the properties into an external file and read it with the maven properties plugin where needed. That would be obviously in the bom and in the pom file where we need to get the version of the dependency. However, since the bom is not packaged as a jar, so the path would have to be hard-coded.

I could fix it by duplicating the properties to two places, but I don't want to do that. Is there a way to get the version of a dependency, e.g. using a property defined by the dependency?

The problem seems to be common enough and I am wondering if we did something wrong in the project structure. What is the standard way to centralize properties in this case?

like image 940
Jens Avatar asked Aug 30 '17 14:08

Jens


People also ask

What is use of BOM in Maven?

What Is Maven BOM? BOM stands for Bill Of Materials. A BOM is a special kind of POM that is used to control the versions of a project's dependencies and provide a central place to define and update those versions.

What is BOM import?

The BOM Import module, located in the Integrations group, is an add-on module that can be installed from the. Plugin module. After installing the plugin, a new module is added that allows the user to import files (csv, xlsx, xls), create a mapping, and import the needed parts, products, and BOMs.

What is Maven BOM in gradle?

Maven's dependency management includes the concept of a bill-of-materials (bom). A bom is a special kind of pom that is used to control the versions of a project's dependencies and provides a central place to define and update those versions.

What is Maven Dependencymanagement?

What Is Maven Dependency Management? Dependency management in Maven allows teams to manage dependencies for multi-module projects and applications. These can consist of hundreds or even thousands of modules. Using Maven can help teams define, create, and maintain reproducible builds.


2 Answers

You can try using the BOM as the parent of your parent module as a BOM is technically some kind of minimal version of a POM. This is what the official Maven project describes here:

http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

I don't like this solution, because if you already extend from a parent, you get into a multi-inheritance problem here.

It appears that a BOM is not fulfilling your requirements. It only assembles a bunch of dependencies like an extract of a dependency management section of a parent project. However its internal structure should not matter to your project. If the BOM changes structurally, your project won't be influenced by that. Perhaps it's a more proper solution not to use a BOM here, but instead pick the dependencies and use your own version property here. Depends a little bit on how complex the BOM is.

So either use the BOM as a parent or dismiss the BOM at all, since you need more than your BOM gives you.

like image 142
Daniel Heid Avatar answered Oct 25 '22 22:10

Daniel Heid


The actual purpose about BOM import is precisely to avoid having to declare the exact version of the dependencies declared in the BOM. So, consider that you have a BOM witch declares a dependency like

<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>${guice-version}</version>
</dependency>

(we asume your BOM also declares the property in it). So then, in your projects, you can declare the guice dependency without having to determine the version attribute as it is inherited from the BOM.

<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
</dependency>

The benefit is that if you change your BOM version, this kind of dependencies will be updated accorndingly without having to do any change in the pom.xml of your project!

like image 31
Carles Iglesias Avatar answered Oct 26 '22 00:10

Carles Iglesias