This appears to be a simple question but I found it difficult due to maven's extremely rigorous paradigm of lifecycles and phases:

Assuming that in a multi-module maven project, several plugins are used in various phases to rewrite the pom.xml to more effective versions, notable examples are:

  • maven-shade-plugin (if <createDependencyReducedPom> is enabled): when the shaded uber-jar needs to be published, the plugin can shrug off dependencies that doesn't need to be included. ALWAYS execute in package phase.

  • flatten-maven-plugin: allows module's published pom.xml to be no longer depending on parent's pom, by replacing property references with their actual values. Can be executed in any phase, but to maintain interoperability with maven-shade-plugin it is also confined to package phase (see https://issues.apache.org/jira/browse/MSHADE-323)

When they are combined with other modules, It appears that maven reactor build engine frequently fumbles with which version of the rewritten pom to be used to calculate transitive dependency. Ideally, the final version after package phase should be used. But in the latest maven version (3.6.3) it is only capable of using the pom.xml BEFORE both rewritting, with no reduced dependencies & all properties not replaced properly.

My questions are:

  1. What's the point of this design? Why using a half-baked pom.xml when all plugins explicitly replaced it?

  2. How to override this behaviour such that the final version of pom.xml is always generated and used, regardless of the maven goal being requested?

UPDATE 1: For the moment I'm using a simple circumvention by:

I'm not a big fan of the shell script, and I think this betrayed the platform-agnostic feat which the JVM community cherished. So if you have a better solution, please post here and I will accept it based on popularity.

Thank you so much for your opinion

1

There are 1 answers

4
khmarbaise On

The first thing is: maven's extremely rigorous paradigm of lifecycles and phases: those lifecycles and phases have very good reasons.

Furthermore you mentioned that several plugins rewrite pom.xml file. The only examples are maven-shade-plugin and flatten-maven-plugin as you mentioned.

Apart from that as you mentioned maven-shade-plugin intention:

This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.

The intention is to shade the dependencies (unpack the jars and repackage into a single jar) and make an executable jar (this can also being done with the maven-assembly-plugin) of it...not to shrug off dependencies.

The idea of flatten-maven-plugin is to remove parts of a pom file which are not needed for later consumption(Build POM vs. Consumer POM). Currently this part will become part of Maven Core with Maven 3.7.0... This is a big first step to separate build pom and the consumer pom.

So let us come to the point of the reactor build engine which is designed to define the order of build based on dependencies.

Ideally, the final version after package phase should be used

So that would mean to have different orders and different dependencies (including transitive dependencies) between the phases before package and after package (for each execution of such plugin). This would result in non repeatable results. Apart from things to recalculate the whole dependency tree etc.

But in the latest maven version (3.6.3) it is only capable of using the pom.xml BEFORE both rewritting, with no reduced dependencies & all properties not replaced properly.

This is also true for all previous versions as well. Furthermore the pom.xml is read at the very beginning of the build...

What's the point of this design? Why using a half-baked pom.xml when all plugins explicitly replaced it?

What exactly would you like to know? Also mentioned only two plugins (and not all plugins) with different intentions.

How to override this behaviour such that the final version of pom.xml is always generated and used, regardless of the maven goal being requested?

There is no option to override this behaviour cause it does not exist. This would mean to rewrite large parts of Maven core.