mavenmaven-modulemaven-reactor

How does Maven order modules in the reactor


Questions like this haven been asked over and over but somehow they just focus on dependencies. So according to the maven documentation the build order is determined as follows.

  • 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 <modules> element (if no other rule applies)

The first rule is quit clear e.g. if module A is dependent on module B the latter is build first.

The fifth rule (last) is quite clear as well. If the former three rules do not apply we look at the order in the module section.

The other two rules are not that clear to me. English is not my native language but I'm wondering if rule two contains a typo of some sort.

I'm looking for a simple example that explains these two rules in some detail.


Solution

  • Let's go through them one by one.

    • a project dependency on another module in the build

    This means that if a module A has a dependency on a module B, then B must be built before A. This handles the case where, in the POM of A, you'd have:

    <dependencies>
      <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>B</artifactId>
        <version>${project.version}</version>
      </dependency>
    </dependencies>
    
    • a plugin declaration where the plugin is another modules in the build

    This means that if a module A uses a Maven plugin which is a module B, then B must be built before A. This handles the case where, in the POM of A, you'd have:

    <build>
      <plugins>
        <plugin>
          <groupId>${project.groupId}</groupId>
          <artifactId>B</artifactId>
          <version>${project.version}</version>
        </plugin>
      </plugins>
    </build>
    
    • a plugin dependency on another module in the build

    This means that if a module A uses a Maven plugin that has a dependency on a module B, then B must be built before A. This handles the case where, in the POM of A, you'd have:

    <build>
      <plugins>
        <plugin>
          <groupId>some.plugin.groupId</groupId>
          <artifactId>some.plugin.artifactId</artifactId>
          <version>some.version</version>
          <dependencies>
            <dependency>
              <groupId>${project.groupId}</groupId>
              <artifactId>B</artifactId>
              <version>${project.version}</version>
            </dependency>
          </dependencies>
        </plugin>
      </plugins>
    </build>
    

    Note that this rule is applied after the last one, so even if the plugin itself is also a module of the build, it will be built before, making sure it is safe to resolve the dependencies.

    • a build extension declaration on another module in the build

    This means that if a module A declares to use as extention a module B, then B must be built before A. This handles the case where, in the POM of A, you'd have:

    <build>
      <extensions>
        <extension>
          <groupId>${project.groupId}</groupId>
          <artifactId>B</artifactId>
          <version>${project.version}</version>
        </extension>
      </extensions>
    </build>
    
    • the order declared in the <modules> element (if no other rule applies)

    When none of the previous rules were applied, the order is the order of the <modules>, which would look like in the POM of the aggregator project:

    <modules>
      <module>A</module>
      <module>B</module>
    </modules>
    

    A would be built before B if none of the previous rules applied.