Search code examples
javamavendependency-managementcircular-dependencymaven-bom

How to Manage dependencies in Maven Muti Project across Multiple Maven Project


I'm having a situation with maven

── bom-porject
    ├── pom.xml 

This is bom proejct is just used to dependency management for external maven dependecy.

This project just publishes a pom file to maven repo

This bom is imported to different projects developed via <dependency Management>

Then I have another a project

── project-libs-root
   ├── module-lib-database
   │   └── pom.xml <--- Module lib database POM 
   ├── module-lib-conversions
   │   └── pom.xml <--- Module lib conversion POM
   └── pom.xml     <--- project-libs-root

This is some common libraries used by all appliaction that I'm developing .

In project-libs-root pom.xml import bom-porject pom.xml using

<dependencyManagement>

I did this to get access to dependecies defined in bom-project

Then I have another maven project

── application-root
   ├── module-app-db
   │   └── pom.xml <--- Module apllication database POM
   ├── module-app-domain
   │   └── pom.xml <--- Module application domain POM
   ├── module-app
   │   └── pom.xml <--- Module application POM (this is a deployment)
   └── pom.xml     <--- application-root  

This is an application This application-root pom.xml importing project-libs-root pom.xml via <dependencyManagement>.

By doing this I got access to bom-porject pom.xml and dependencies defined in it

The confusing part around internal modules and manging it's dependecy in project using it For example

Suppose if i need to use artifact module-lib-database from project-libs-root in module-app-db artifact of application-root , Where should i mention dependency for module-lib-database

Currently i'm explicity calling it inside <dependecies> tag of module-app-db pom.xml

Is there any way I can define it in project-libs-root and brought it down to application via <dependencyMangement> tag


Solution

  • Probably, this is how I would have tried to setup the projects as per your description:

    parent-bom - this would be having your all third party dependencies declared to maintain one version across the other projects

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.example</groupId>
      <artifactId>parent-bom</artifactId>
      <packaging>pom</packaging>
      <version>1.0-SNAPSHOT</version>
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>23.0</version>
          </dependency>
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
          </dependency>
        </dependencies>
      </dependencyManagement>
    </project>
    

    lib-parent The other multi module project of the common lib as described by you.

    |-lib-parent
    | |
    | |- lib-db
    | |   |
    | |   | - pom.xml
    | | ...
    | |- pom.xml
    

    lib-parent

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.example</groupId>
      <artifactId>lib-parent</artifactId>
      <packaging>pom</packaging>
      <version>1.0-SNAPSHOT</version>
    
      <modules>
        <module>lib-db</module>    
        <module>lib-bom</module>
      </modules>
    
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>com.example</groupId>
            <artifactId>parent-bom</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
        </dependencies>
      </dependencyManagement>
    </project>
    

    lib-db

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>com.example</groupId>
        <artifactId>lib-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
      </parent>
      <artifactId>lib-db</artifactId>
      <packaging>jar</packaging>
    
      <dependencies>
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
        </dependency>
      </dependencies>
    
    </project>
    

    lib-bom

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
       <groupId>com.example</groupId>
       <artifactId>lib-parent</artifactId>
       <version>1.0-SNAPSHOT</version>
     </parent>
     <artifactId>lib-bom</artifactId>
     <packaging>pom</packaging>
    
     <dependencyManagement>
       <dependencies>
         <dependency>
           <groupId>${project.groupId}</groupId>
           <artifactId>lib-db</artifactId>
           <version>${project.version}</version>
         </dependency>
       </dependencies>
     </dependencyManagement>
    
    </project>
    

    Finally, application-parent project which will use dependencies from parent-bom and common lib from lib-parent project.

    |- application-parent
    | |
    | |- module-app-db
    | |  |
    | |  | - pom.xml
    | |  ...
    | |- pom.xml
    

    application-parent

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.example</groupId>
      <artifactId>application-parent</artifactId>
      <packaging>pom</packaging>
      <version>1.0-SNAPSHOT</version>
    
      <modules>
        <module>module-app-db</module>    
      </modules>
    
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>parent-bom</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
          <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>lib-bom</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>pom</type>
          <scope>import</scope>
        </dependency>
       </dependencies>
      </dependencyManagement>
    </project>
    

    module-app-db

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>com.example</groupId>
        <artifactId>application-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
      </parent>
      <artifactId>module-app-db</artifactId>
      <packaging>jar</packaging>
    
      <dependencies>
        <dependency>
          <groupId>${project.groupId}</groupId>
          <artifactId>lib-db</artifactId>
        </dependency>
      </dependencies>
    
    </project>
    

    To build above project, here are the steps:

    $cd /path/to/parent-bom-dir && mvn clean install
    $cd /path/to/lib-parent-dir && mvn clean install
    $cd /path/to/application-parent-dir && mvn clean install
    

    Let me know if this works with you or not.