views:

455

answers:

4

I have a MOJO I would like executed once, and once only after the test phase of the last project in the reactor to run.

Using:

if (!getProject().isExecutionRoot()) {
        return ;
}

at the start of the execute() method means my mojo gets executed once, however at the very beginning of the build - before all other child modules.

A: 

Normally, this is a matter of configuration. You might have to setup a project just for the mojo and make it dependent on all of the other projects. Or you could force one of the child projects to be last by making it dependent on all of the other children.

sblundy
A: 

I think you might get what you need if you use the @aggregator tag and bind your mojo to one of the following lifecycle phases:

  • prepare-package
  • package
  • pre-integration-test
  • integration-test
  • post-integration-test
  • verify
  • install
  • deploy
bmatthews68
That may work, however, the MOJO needs to be executed after the test phase.ie: mvn testshould run all the tests in all sub-modules and then run the MOJO of the execution root.
npellow
+2  A: 

The best solution I have found for this is:

/**
 * The projects in the reactor.
 *
 * @parameter expression="${reactorProjects}"
 * @readonly
 */
private List reactorProjects;

public void execute() throws MojoExecutionException {

    // only execute this mojo once, on the very last project in the reactor
    final int size = reactorProjects.size();
    MavenProject lastProject = (MavenProject) reactorProjects.get(size - 1);
    if (lastProject != getProject()) {
        return;
    }
   // do work
   ...
}

This appears to work on the small build hierarchies I've tested with.

npellow
+1  A: 

There is a Sonatype blog entry that describes how to do this. The last project to be run will be the root project as it will contain module references to the rest. Thereforec you need a test in your mojo to check if the current project's directory is the same as the directory from where Maven was launched:

boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase(basedir.toString());

In the referenced entry there is a pretty comprehensive example of how to use this in your mojo.

Rich Seller