Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I run a Maven Plugin on all modules?

I have a custom plugin that I run on all our projects as part of the release:perform goal.

We are just starting to use multi-module builds, and I notice that my plugin only runs at the top module. What do I have to do to my plugin to make it run on all the modules individually at the end of the release? Do I have to iterate through them in the plugin code itself? If so, is there an example of doing that, because from what I see, MavenProject.getModules() just returns a list of String names of those modules, and I can't see how to get info for those modules (my plugin needs the groupId:artifactId:version of each, and in this case, the modules do not always have the same version).

I've tried with and without @aggregator, but that doesn't change anything with respect to my problem.

I'm assuming this is the same case as running the plugin directly (not tied to a phase) from CLI, which also only runs on the top-level of the project, and reports SKIPPED for all the sub-modules.

I am using Maven 3.0.3.

like image 626
Ben Avatar asked May 12 '11 21:05

Ben


People also ask

How do I run a multi-module project in Maven?

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.

Can two Maven modules depend on each other?

Because modules within a multi-module build can depend on each other, it is important that the reactor sorts all the projects in a way that guarantees any project is built before it is required. The following relationships are honoured when sorting projects: a project dependency on another module in the build.


2 Answers

I had the same problem with my Maven plugin. It was only being invoked once (generally for the first module in the reactor), and I eventually traced it to the fact that my plugin had the Maven annotation "@requiresProject false". It seems that the Maven Reactor only invokes such plugins once. Once I switched to "@requiresProject true", my mojo was invoked once for each module. I wasn't hooking into release:perform, so YMMV.

As for accessing all the modules, instead of using MavenProject.getModules() which gives their names, you could inject their MavenProject objects like this:

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

Watch out for @aggregator when binding to lifecycle phases. "When bound to a lifecycle, an aggregator mojo can have some nasty side-effects. It can force the execution of the ... lifecycle phase to execute ahead of time, and can result in builds which end up executing the ... phase twice." ref

How do you force a maven MOJO to be executed only once at the end of a build? has some alternatives to @aggregator.

like image 74
seanf Avatar answered Sep 25 '22 17:09

seanf


Using the new maven-plugin-annotations you can also inject:

@Component
private MavenSession session;

and call session.getProjects() (Maven 3) or session.getSortedProjects() (2).

like image 43
Jesse Glick Avatar answered Sep 23 '22 17:09

Jesse Glick