Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
-
Maven 4.0.0-alpha-1-SNAPSHOT
Description
Background
In MNG-6566, we fixed the following scenario:
- an invocation of Maven with for example compile package,
- while the project declares a plugin goal in its build,
- that requires a fork of the compile goal.
In that scenario, the compile goal would run twice: once because of the package goal that was in the CLI invocation, once because the plugin requires it.
Context
It turns out that this fix is not working for multi-module builds. Consider a project structure like this, where
- the javadoc:aggregate-jar is bound to the package phase of the root module,
- the root module declares module-a and module-b as its child modules.
. ├── module-a │ ├── pom.xml │ └── src ├── module-b │ ├── pom.xml │ └── src └── pom.xml
Invoking mvn clean package will cause the following to happen:
>>>> module-a <<<< clean @ module-a compile @ module-a jar @ module-a >>>> module-b <<<< clean @ module-b compile @ module-b jar @ module-b >>>> parent <<<< clean @ parent javadoc:aggregate-jar @ parent (starts forking) > compile @ module-a > compile @ module-b javadoc:aggregate-jar @ parent
(Aside: although clean may not be necessary, it's still a common thing to do; leaving clean out of the invocation does not fundamentally change the observation below)
Bug
Running compile on module-a and module-b as part of the aggregate-jar forking is not necessary, as that has been done just before aggregate-jar started.
Of course, the Maven Compiler Plugin is smart enough to see that the source code hasn't changed since the class files were written, and it will log "Nothing to compile - all classes are up to date". But this is only an example, and other plugins may not be so smart.
Considerations
For many situations, a "to be forked" goal (compile, in the above example) that was already executed can be safely skipped as part of the "forking" goal (aggregate-jar, in the above example). But this may not always be the case:
Edge case(s)
If the order of goals would've been mvn package clean, the execution plan would look like this:
>>>> module-a <<<< compile @ module-a jar @ module-a clean @ module-a >>>> module-b <<<< compile @ module-b jar @ module-b clean @ module-b >>>> parent <<<< javadoc:aggregate-jar @ parent (starts forking) > compile @ module-a > compile @ module-b javadoc:aggregate-jar @ parent clean @ parent
Removing the "to be forked" goals that had already been executed would mean removing the second compile on both module-a and module-b. As a result, the aggregate-jar goal would fail (no classes present). This is of course an insane example, but maybe there are more situations where one of the goals on the child modules could alter or even destroy a prerequisite of the aggregating/forking mojo? I am not sure if we should account for that / support that.
Attachments
Attachments
Issue Links
- is related to
-
MNG-7991 refactor "aggregator" goal feature
- Open
- relates to
-
MSHARED-1044 Required report phase are executed many times in the same Maven session
- Open
-
MSITE-650 Problem with multiple executions of surefire within site plugin 3.0
- Open
-
MNG-7156 Parallel build can cause issues between clean and forked goals
- Closed
-
MNG-250 make aggregation feasible
- Closed