Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences between a multi-module project and a parent project

In multi-module project in Maven, we have a parent pom with modules defined in <modules> tag, and in each module, we define which the parent pom is.

  • Why this two-way definition?

  • Why not define the relationship between them just in the parent part of the modules

  • How am I supposed to reuse modules if they are always bound to one parent?

like image 350
Gilad Baruchian Avatar asked Aug 06 '17 13:08

Gilad Baruchian


People also ask

What is the use of multi-module project?

Advantages of a Multi-Module ProjectIt provides a great ability to build all sub-modules only with a single command. We can run the build command from the parent module. While building the application, the build system takes care of the build order.

What is a multi-module project?

A multi-module project is built from an aggregator POM that manages a group of submodules. In most cases, the aggregator is located in the project's root directory and must have packaging of type pom. The submodules are regular Maven projects, and they can be built separately or through the aggregator POM.

What is a Maven parent project?

This POM is the common parent of all of the Maven components in the Apache Maven project. Most of its contents are pinning down version numbers of plugins. It does provide minimal dependencyManagement for plexus-component and plugin-tools annotations.

What is multi-module project in spring boot?

A Spring Boot project that contains nested maven projects is called the multi-module project. In the multi-module project, the parent project works as a container for base maven configurations. In other words, a multi-module project is built from a parent pom that manages a group of submodules.


2 Answers

Why this two-way definition?

It is not mandatory. It is a design choice.

Why not define just in the parent?

If you define them only in the modules tag of the parent pom, you will only use the reactor/aggregation feature of Maven.

1) Aggregation (<modules> declaration in the super aggregator project) provides mainly these features:

  • Collects all the available modules to build
  • Sorts the projects into the correct build order
  • Builds the selected projects in order

Aggregation module is enabled by declaring the modules to aggregate in the parent pom:

<modules>
    <module>my-child</module>
    <module>my-other-child</module>
</modules>

But aggregation doesn't provide inheritance.

2) Project inheritance (<parent> declaration in the child modules) provides the inheritance of multiple things from the parent declaration to the child module :

From the actual documentation, most elements from the parent POM are inherited by its children:

  • groupId
  • version
  • description
  • url
  • inceptionYear
  • organization
  • licenses
  • developers
  • contributors
  • mailingLists
  • scm
  • issueManagement
  • ciManagement
  • properties
  • dependencyManagement
  • dependencies
  • repositories
  • pluginRepositories
  • build
  • plugin executions with matching ids
  • plugin configuration
  • reporting
  • profiles

Inheritance is enabled by declaring the parent artifact in the child poms:

<parent>
    <groupId>my-group</groupId>
    <artifactId>my-parent</artifactId>
    <version>1.0.0</version>
</parent>

<!-- You can note that groupId and version are not filled for the current project.
 These are optional as inherited from the parent -->
<artifactId>my-artifact</artifactId>

In fact, you can use project inheritance, project composition, none of them or both.

It is really a design choice that should be done according to the relation between the projects and their requirements.

You may refer to this interesting point on the Maven documentation about these two features:

Project Inheritance vs Project Aggregation

If you have several Maven projects, and they all have similar configurations, you can refactor your projects by pulling out those similar configurations and making a parent project. Thus, all you have to do is to let your Maven projects inherit that parent project, and those configurations would then be applied to all of them.

And if you have a group of projects that are built or processed together, you can create a parent project and have that parent project declare those projects as its modules. By doing so, you'd only have to build the parent and the rest will follow.

But of course, you can have both Project Inheritance and Project Aggregation. Meaning, you can have your modules specify a parent project, and at the same time, have that parent project specify those Maven projects as its modules.

To illustrate using an example.

Here is a multi-module project's parent pom.xml.

<!-- PARENT POM -->
<groupId>com.example</groupId>
<artifactId>parent-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
    <module>child-module</module>
</modules>

And here is the Child Pom.

<!-- CHILD POM -->
<parent>
    <groupId>com.example</groupId>
    <artifactId>parent-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>chile-module</artifactId>

Here, child-module inherits parent-demo, but parent-demo does not use any inheritance.

And if you want, your parent-demo to also use inheritance, you can configure your parent-demo like below.

<!-- PARENT POM -->
<parent>
    <groupId>com.example</groupId>
    <artifactId>parent-deps</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <relativePath>../parent-deps</relativePath>
</parent>
<artifactId>parent-demo</artifactId>
<packaging>pom</packaging>

<modules>
    <module>child-module</module>
</modules>

And now, your parent-demo is also inheriting configurations from parent-deps which are cascaded down to child-module as well (unless ofcourse parent-demo decides to override them).

like image 134
davidxxx Avatar answered Oct 13 '22 05:10

davidxxx


Because when you are building some submodule, it should now some meta information, such as dependency version for example, and it's usually a better practice to put this dependencies into parent pom dependencyManagement, because I would make all submodules use the same library version. Also there is another meta information that could be useful, like properties.

So, all in all when you are building a particular submodule, maven should know some information which you usually want to set up in the parent pom.

I believe there can be more reasons for that, but it's the most obvious for me.

If you want to reuse modules in my opinion then you need these modules to be a library, and add them via dependency tag as a library.

like image 29
Ruslan Akhundov Avatar answered Oct 13 '22 05:10

Ruslan Akhundov