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:
What's the point of this design? Why using a half-baked pom.xml when all plugins explicitly replaced it?
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:
splitting the first module into an independent maven project, with both maven-shade and flatten-maven plugin invoked at package phase. (I have no direct evidence but I suspect this is how repackaged dependencies like
spark-project.hive
https://mvnrepository.com/artifact/org.spark-project.hive/hive-common was made, see https://issues.apache.org/jira/browse/SPARK-20202 for relevant discussion)use a shell script to compile/publish the above project and the main multi-module project sequentially.
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
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:
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.
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.
This is also true for all previous versions as well. Furthermore the pom.xml is read at the very beginning of the build...
What exactly would you like to know? Also mentioned only two plugins (and not all plugins) with different intentions.
There is no option to override this behaviour cause it does not exist. This would mean to rewrite large parts of Maven core.