4

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

tribbloid
  • 4,026
  • 14
  • 64
  • 103
  • So what is the concrete problem that you encounter? Why is it a problem for you if Maven reads the build POM, and not the POM that is finally deployed? – J Fabian Meier Sep 07 '20 at 08:25
  • the consequences are: 1. the IDE will attach useless jars when executing tests & profiling. 2. other plugins in downstream modules that rely on transitive dependency as evidence will act strangely. Due to JVM's class loading algorithm these problems are most likely be dormant in runtime, but there is no guarantee – tribbloid Sep 07 '20 at 18:00
  • Sorry, I still don't get why you need a circumvention and cannot just build. Could you give a concrete example of what goes wrong? – J Fabian Meier Sep 08 '20 at 06:51
  • I guess it would help the question a lot if you could add a concrete example. – J Fabian Meier Sep 14 '20 at 12:17

1 Answers1

2

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.

khmarbaise
  • 92,914
  • 28
  • 189
  • 235
  • "...not to shrug off dependencies", not anymore, `` is an official feature and is enabled by default – tribbloid Sep 06 '20 at 21:23
  • FYI https://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html#createDependencyReducedPom. Considering this information, you almost suggested that maven is a sand castle and should be abandoned – tribbloid Sep 06 '20 at 21:27
  • 1
    I know that this option exists and the intention is to remove the dependencies which are shaded in the resulting jar and not deps which are not used. Otherwise a pom of the using project would be used which would be wrong in the case of maven-shade-plugin usage. Furthermore `Considering this information, you almost suggested that maven is a sand castle and should be abandoned` Hm...I'm not sure what you like to express with this? Where have I suggested/concluded that? And I don't see the relationship to abandoned Maven? – khmarbaise Sep 06 '20 at 21:39
  • Sorry I was being cynic, I'm not abandoning maven. However to mitigate the consequence of this paradigm (see my comment of the question), now I have to break a monolithic project into 2, and use a glue language to duct tape them together just to get the pom version right. Should I do this every time for such trivial causes? If the glue language goes rampant everywhere will the build pipeline degrade into another ant? These are the questions I have to ask for next 10 years – tribbloid Sep 07 '20 at 18:24