While working on IDE support for running Maven on multi-module projects [1] I have run up against what seems to be a fundamental limitation of --also-make. This "reactor mode" works fine when the specified goal is standard across all lifecycles in the tree, such as 'install' or 'package'.

But frequently you would want to run some special goal which only makes sense on a particular packaging, or otherwise only for certain kinds of modules. Typically this would be some sort of "run" goal. As a simple example, in Hudson main sources the 'core' project (using a custom packaging akin to jar) supports just the usual goals such as install, while the 'war' project which depends on 'core' has war packaging and supports a hudson-dev:run goal to start Jetty for interactive testing. To test code changes, normally you build core, then run war.

Similarly, when developing NetBeans Platform applications, you typically have an aggregator/parent, which contains one project with nbm-application packaging supporting the nbm:run-platform goal to start the application in development mode, which depends on a bunch of module projects with nbm packaging supporting the usual package/install phase. If you make a change in a module and want to test it interactively, you must first build the module, then build & run the app; the module project cannot in general "know" how to start the app together with all its siblings.

These scenarios seem to call out for make mode. The problem is that 'mvn --also-make --projects <main> <goal>' only permits specification of a single goal, which will be run in all the projects encountered; 'mvn -am -pl main something:run' dies with an error on the first dependency since it does not use the plugin with 'something' prefix. In these examples, what is wanted is to run 'install' (or perhaps 'package') on all the discovered dependencies, followed by something like 'run' on the "main" project.

The only workaround I can find is to run separate chained Maven commands: 'mvn -am -pl main install && mvn -pl main run'. While this works, it is slower and clumsier, and produces two sets of output.

I can imagine several ways Maven could support this use case:

1. Some distinguished Maven CLI argument which would run sequential commands, but within the same JVM, sharing cached plugins and project metadata, and producing a single summary. E.g.:

  mvn -am -pl main install -then -pl main run

A bit crude, and not very friendly to parallel builds, but at least simple. This of course could be used for other purposes, such as passing -DskipTests only to certain subprojects.

2. Some way of telling --also-make to use a different goal for dependencies 
than for the specified project, e.g.

  mvn --also-make-goals -pl main install run

where for each project in the reactor, only as many goals in the given sequence 
would be run as are actually available.

3. Some way of declaring in general (say, plugin.xml#//mojo/dependencyGoal) 
that a certain goal presupposes a different goal be used on reactor 
dependencies, so that plain

  mvn -am -pl main run

would automatically invoke just 'install' (or 'package') on the calculated dependencies. Note that this could be useful even with common plugins; 'install' on a jar project really only needs to 'package' its jar dependencies. (For compatibility reasons, a different switch than --also-make could be introduced to enable the new behavior.)

Perhaps --also-make-dependents could benefit from per-project goal selection as 
well; offhand I cannot think of a use case.

Are there plans for a more clever make mode? The 3.0 compatibility guide 
implies that there are, but does not give any specifics.


[1] https://netbeans.org/bugzilla/show_bug.cgi?id=189417


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to