Build order of Maven multimodule project?
Asked Answered
W

4

74

The situation is, I have two Maven multimodule projects with the same structure:

Parent
    - Module 1
    - Module 2

When I build project 1, I see that parent is built first (order is parent->module1->module2). However for project 2, parent is built at last (order is module1->module2->parent). Why are the two projects have different build orders? Furthermore, how can I manually control the build order?

Update 1:
Both parent projects are simple POM projects without source code, so I can't explain the build order as per the dependency graph.

Update 2:
The parent POMs are the same except the GAV and child module names:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>parent-group-id</groupId>
    <artifactId>parent-artifact-id</artifactId>
    <version>parent-version</version>
    <packaging>pom</packaging>
    <name>parent-name</name>
    <modules>
        <module>module-1</module>
        <module>module-2</module>
    </modules>
</project>
Watterson answered 21/6, 2012 at 4:40 Comment(4)
Possible duplicate of Impose build order for a multi-project in MavenQuindecennial
How do you invoke the two builds? The details here may be important.Chirpy
I've encountered this behaviour in a multimodule project due to a version mismatch. The root pom.xml version was bumped manually, but the submodule pom.xml still referred to the old parent version.Nostoc
Since maven 3.5.0+ (2017), you can avoid repeating the parent version in each module, look at: #10582554Nostoc
I
63

The build order is determined by the Maven reactor which is a mechanism that automatically ensures correct build order for multimodule builds by sorting the projects.

See the official documentation for how it works.

It says:

The following relationships are honoured when sorting projects:

  • a project dependency on another module in the build
  • a plugin declaration where the plugin is another modules in the build
  • a plugin dependency on another module in the build
  • a build extension declaration on another module in the build
  • the order declared in the element (if no other rule applies)

You can't manually control the build order. If you want to change the order you have to make changes to your project that influence the reactor sort order.

Issie answered 21/6, 2012 at 4:57 Comment(3)
But this doesn't explain why the two projects have different build orders.Watterson
It shouldn't be different. Isn't any more differences ? Have the childs the same parent ?Evoy
Check the parent version in the child modulesNostoc
O
14

At a high level, the build order is based on a topological sort of the module dependency graph.

EDIT: Question for you. I understand that project 1 contains two modules and so does project 2. But do the modules in project 2 explicitly declare the "parent" pom as a parent? I'm thinking that perhaps your project 1 modules explicitly declare the parent pom, and the project 2 modules don't. Which would mean that the project 2 "parent" isn't really a parent at all and therefore doesn't have to be built before the modules. That's my guess anyway.

Obsolescent answered 21/6, 2012 at 5:0 Comment(2)
But both parent projects are simple POM projects without any source code. The dependency graph doesn't make sense here.Watterson
Referencing a parent POM is also a dependency.Featheredge
S
8

I've been having this issue lately with CentOS 7. I updated Maven to 3.5.3 from 3.0.5 and the problem has been solved. If anyone have this issue as well you can try doing that first.

Shutin answered 30/5, 2018 at 10:55 Comment(2)
Welcome to SO. This seems an unlikely answer to such an old question. See stackoverflow.com/help/how-to-answer for help on how to answer questions.Intervale
I wrote it for people like me. I had that issue and couldn't find anything. And then i solved by myself and wrote it to here so if people live that issue and Google it they can find something.Brandabrandais
F
2

Summary

Why?

Maven is using <module> declarations to determine the list of modules to include in the current run. Maven is using <parent> declaration to generate effective POM for each included module, which is then used to execute the build for that module.

In Project 1, each of module1 and module2 specify parent module in <parent> section. In Project 2, neither module1 nor module2 specify parent module in <parent> section.

How can I manually control the build order?

By changing dependencies between modules, including <parent>, <dependencies>, plugin dependencies, etc. as described in the official documentation.

Please check also Introduction to the POM for the discussion on aggregation and inheritance.


Details

There are 4 possible scenarios of module relationships in Maven in terms of aggregation (<module> declaration) and inheritance (<parent> declaration).

Let's assume a module A with packaging pom and a module B (packaging does not matter). The module A could either be a parent or an aggregator. The module B could either reference A as parent or not.

Case 1:

Neither A nor B reference each other - the modules are independent. The Maven can not control build order, each module gets built independently, with manual build order control.

Case 2:

The module A includes the module B in <modules>. The module B does not declare A as parent. The module A is an aggregator for the module B in this case.

  • Maven invocation mvn -f A/pom.xml will first build B, and then A.
  • Maven invocation mvn -f B/pom.xml will build B only.

Case 3:

The module A includes the module B in <modules>. The module B declares A as parent. The module A is both the parent and the aggregator (reactor) for the module B in this case.

  • Maven invocation mvn -f A/pom.xml will first build A, and then B.
  • Maven invocation mvn -f B/pom.xml will build B only, but will use the POM of A to generate effective POM of B by resolving it either from the local repository or by following /project/parent/relativePath.

Case 4:

The module A does not include the module B in <modules>. The module B declares A as parent. The module A is the parent for the module B in this case.

  • Maven invocation mvn -f A/pom.xml will build A only.
  • Maven invocation mvn -f B/pom.xml will build B only, but will use the POM of A to generate effective POM of B by resolving it either from the local repository or by following /project/parent/relativePath.
Featheredge answered 24/2, 2021 at 13:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.