edwin
edwin

Reputation: 8081

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

I'm having a situation with maven

── bom-project
    ├── pom.xml 

This bom project is just used for dependency management with external maven dependency.

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 applications that I'm developing.

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

<dependencyManagement>

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

Then I have another maven project

── application-root
   ├── module-app-db
   │   └── pom.xml <--- Module application 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-project pom.xml and dependencies defined in it.

The confusing part around internal modules and managing it's dependencies in project using it. For example, suppose I need to use artifact module-lib-database from project-libs-root in module-app-db artifact of application-root, where should I mention dependencies for module-lib-database?

Currently I'm explicitly calling it inside the <dependencies> tag of module-app-db pom.xml

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

Upvotes: 2

Views: 3976

Answers (3)

Rishikesh Darandale
Rishikesh Darandale

Reputation: 3310

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.

Upvotes: 4

OhadR
OhadR

Reputation: 8839

If I understand your requirements fully, I would suggest having a "parent pom" for the internal dependencies. Meaning, this pom file would have <dependenciesManagement> with all internal dependencies.

This parent pom will have a parent, which is another parent pom, with the 3rd-party dependencies. Other components can use this parent-pom directly, without (bypassing) the "internal" parent pom.

Hope that makes sense.

Upvotes: 0

senape
senape

Reputation: 342

I don't have enough reputation to comment, so I'm using an answer, but if you comment I can reply.

As I remember, a BOM is created to define a custom library, with all the dependencies needed to my project(s), and it's used to keep track of the versions in one single place, so that when I update one or more dependencies I don't have to bother modifying all my projects that import them.

Now, I am asking: would it be correct in your project structure to have projects-lib-root shared with all the sub-projects? And in this case, would it make sense to include it within the bom-project?

What do you think?

Upvotes: 0

Related Questions