Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Module inheritance vs aggregation

Tags:

maven

We have a big and deep module structure with three "real" layers of inheritance and three to four layers of module aggregation.

I am fine with the real inheritance: a company wide super-pom, a product-wide parent and a customer-wide parent for customizations of the product.

But I observe that also the "empty" aggregating modules are defined as parents of their submodules.

If the whole concept is the same as in OO, this makes no sense to me if the aggregating modules (they are empty besides their submodules) add no specific configuration to the pom.

Is there any other reason (perhaps operational) why this could be useful?

Sidenote: Introduction to the pom is not clear in this respect: term "parent" is not clear: it can mean super-pom (=parent in inheritance tree) or aggregating pom (=parent in filesystem...)

like image 905
Bastl Avatar asked Jul 05 '13 06:07

Bastl


People also ask

What is aggregation in Maven?

In Maven, project aggregation is similar to project inheritance, except that the change is made in the parent pom instead of the child pom. Maven uses the term module to define a child or subproject, which is part of a larger project. An aggregate project can build all the modules together.

What is a multi-module?

A multi-module project simply manages a group of other sub-projects, or modules. The multi-module relationship is defined from the topmost level downwards. When setting up a multi-module project, you are simply telling a project that its build should include the specified modules.

Why 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.


2 Answers

There is a great problem in the definition of these concepts in the Maven community. You are right with stating that a parent-pom is inheritance and module-pom is composition. But unfortunately the separation of these two concepts have no history in Maven. The Maven documentation says clearly that it is better to separate them. This would result in this ideal structure

app-api/ app-impl/ app-war/ app-parent/ pom.xml 

Where pom.xml is the module pom.

But almost every project you will see in the open source sector does not distinguish between them.

This has a reason: Many plugins do not distiguish between them as well. And even Maven itself assumes another setting: If <relativePath> is not set Maven assumes that the parent is at ... So every project has to point to <relativePath>../app-parent</relativePath> as parent.

The most popular plugin that has huge problems with the mentioned structure is the maven-release-plugin! You will face strange problems when you do not follow the assumption that the module-pom is the parent-pom.

The worst bug is that the release-plugin cannot replace version-properties in your parent and fails because of SNAPSHOT-Dependencies. Your parent perhaps will contain something like this

<properties>     <app-api.version>1.1-SNAPSHOT</app-api.version>     <app-impl.version>1.2-SNAPSHOT</app-impl.version> </properties>  <dependencyManagement>     <dependencies>         <dependency>             <groupId>myorg</groupId>             <artifactId>app-api</artifactId>             <version>${app-api.version}</version>         </dependency>          <dependency>             <groupId>myorg</groupId>             <artifactId>app-impl</artifactId>             <version>${app-impl.version}</version>         </dependency>     </dependencies> </dependencyManagement> 

Normally while releasing these properties would automatically be set to their release versions 1.1 and 1.2. But the release-plugin (tested up to version 2.2.2) fails with a message that the module cannot be released with snapshot dependencies.

If you only "skip" some module-poms this might not be a problem when you define <relativePath> correctly. But you have to try and expect some bugs in Maven plugins. Besides these bugs you are totally right to seperate the poms and I would give it a try if you have the time to make a sandboxed release.

like image 59
Marc von Renteln Avatar answered Oct 06 '22 12:10

Marc von Renteln


The short answer IIUC is, you don't inherit from your aggregation-only poms. You do when your aggregator is the same as your parent, as in the canonical maven structure. But if you separate aggregator from parent, don't inherit from the aggregator

like image 24
Hilikus Avatar answered Oct 06 '22 11:10

Hilikus