Consumer POM of multi-module project should exclude <build> and <dependencies> elements#11639
Consumer POM of multi-module project should exclude <build> and <dependencies> elements#11639desruisseaux wants to merge 2 commits intoapache:masterfrom
Conversation
elharo
left a comment
There was a problem hiding this comment.
build yes
dependencies maybe. I'm not sure.
|
Just in case there is an ambiguity, In the case of multi-module projects, there is a choice:
In approach 1, the content of the project However, approach 1 leads to a lot of duplication in the POM of each Java module. For that reason, I'm now more inclined to approach 2. It also appears to be simpler, because it removes the need to duplicate the work of Maven core into the JAR plugin (because we can inherit the effective POM generated by Maven core). However, approach 2 can work only if we remove |
|
build was originally removed then was reverted since the info has value, how do we plan to keep the information in consumer pom - or rephrased, how do we plan to expose it in a ~stable model? Also the "comes from parent" info should be somewhere to understand why a module get a totally unrelated dependency on consumer land and have more serennity excluding it IMHO - not that rare actually for provided scope for ex. |
It would be easier to answer this question with a use case. Why a user would need build information? Removing the
I do not understand well. The consumer POM get a subset of the dependencies of the project. Which unrelated dependencies are we talking about? |
|
@desruisseaux while we say consumer pom == runtime dependency set we are good, it means we prune optional, provided, test dependencies too. But it also means we prune all other kind of dependencies (javadoc, annotation-processor etc... and extension ones - will start to be complicated, think bundle for OSGi for ex). So basically we keep dependencies almost as this with just the flatten option. The dependency part I'm thinking about is parent gets my-java-util-logging-log-manager, so all children get it even the lib/ module which doesn't care. Loosing the inheritance info makes it harder to understand without checking original sources and automotion is harder if you need an unstable metadata source (build pom). This is part of the pom metadata which are consumed, now it is also common to put metadata in the pom elsewhere, properties are one location, plugins are another one. All that to say that I think we should be able to keep the original info somehow in a normalized way. |
|
Optional, provided and tests dependencies are not in Javadoc and annotation dependencies are no longer in
But this information is not in |
the point is more that we can't drop useful information cause it is not used for a single use case without a proper replacement, think OSGi requirement (~provided scope for ex).
Yes but to complete your PR idea you must remove them from
Well my point was that removing build is an issue we hit so we can't do it now more than before since we dont have a fix for it plus the fact ultimately cleaning up dependencies will be challenging too with the new type workaround. |
This is not a general rule. The encapsulation principle in object oriented programming recommends the opposite: do not expose implementation details unless you have to ("in case of doubt, leave it out"). I'm in favour of this approach. We have the opportunity to remove
This is not the topic of this pull request. This pull request removes all dependencies in the parent consumer POM, and the JAR plugin as proposed reinjects only the dependencies that are declared in
See above: keeping the build is an issue, because it ties us forever for nothing (the dependencies information are not in |
well what is your proposal for people using it, pom.xml is our descriptor, it is a good location to expose data.
once again, we did drop it and had to revert it so it is not a risk but a bug.
it is totally, the topic is "what do we want to keep in consumer pom", there is no real point starting to drop random data without cleaning it all IMHO, just mean we'll have multiple breaking phases
Think it is just your niche/JPMS case but far to be mainstream today so will not cover much sadly, so not a global solution.
I ack that but we need a solution before dropping it, so I'm -1 for this PR until we propose something. |
The reasons why it was reverted are not necessarily valid anymore. If the reason was Javadoc and annotation dependencies, it was a valid reason in Maven 3 but is not valid anymore with the new model since those dependencies are no longer in the
There are two separated discussions:
I know that you dislike JPMS. But this pull request has no impact on non-JPMS users. Keeping Again, please keep in mind that this pull request applies only to projects that use Module Source Hierarchy. If you do not like JPMS, you are not impacted. |
I'll be fine but our ecosystem will be inconsistent, do we want that? 🤔 |
Fully embracing Java modules requires a lot of changes in developer's habit. I don't see any way to avoid inconsistency in the way to declare dependencies (Javadoc and annotation moved from plugin configuration to ordinary dependencies), to declare sources (plugin configuration and |
hmm, this is not the point, the point is that I'd like to avoid a consumer pom to be different if the upstream project is JPMS or not, there is no reason we make it different. |
A consumer POM of a classical Maven project can be a valid 4.0.0 model. But in a multi-module projects, the In other words, in a non-modular project, it is possible to produce a consumer POM in such a way that the users can trust the |
|
@desruisseaux I understood, we still need a way to solve it globally to not have a solution for JPMS, another one for another new feature (subprojects breaking renaming for ex) etc.. One option was to say we do use build pom but we don't have a pivot format yet so no solution so I think this PR must await we have a global solution solving the root issue and enabling user to use the new stable model for future dev - and ack we break for maven 4 once for all. Just my 2 cts |
|
@desruisseaux can we get some unit tests + a property (undocumented is fine) to disable that please? (then will be good to me) |
|
Okay, I will add unit tests during the weekend and will investigate which property could fit. Thanks for the feedbacks. |
|
I see an issue with The current PR strips Suggested refactoring with integrated logic: static Model transformPom(Model model, MavenProject project) {
boolean preserveModelVersion = model.isPreserveModelVersion();
// raw to consumer transform
model = model.withRoot(false).withModules(null).withSubprojects(null);
if (model.getParent() != null) {
model = model.withParent(model.getParent().withRelativePath(null));
}
if (!preserveModelVersion) {
// Downgrade to 4.0.0 compatibility
if (isModular(project)) {
// <sources> element requires 4.1.0+, strip incompatible elements
model = model.withBuild(null);
model = model.withDependencies(null);
}
model = model.withPreserveModelVersion(false);
String modelVersion = new MavenModelVersion().getModelVersion(model);
model = model.withModelVersion(modelVersion);
}
// else: keep model as-is, including <build> and <dependencies> for modular projects.
// Consumer POM will use model version 4.1.0+ if needed.
return model;
}This way:
No new property needed - the existing Code suggestion: The Also:
|
|
I forgot about Regarding Said otherwise, in a multi-module project, |
I should have looked again in 508 ... On the other hand I was not aware that there was already some stuff to create consumer POM in the core. Considering that, handling of (creating consumer POMs in this case) it is perhaps best to either leave it completely in the core (and thereby unify handling accross plugins) or move it completely to the Plugins. IIRC we already discussed this topic elsewhere. Perhaps it is OK to initially do something at first in single plugins and only move it to the core when it stabilizes? In this case I slightly tend to move the Maven Model > 4.1.0 based consumer POM generation to the core as soon as possible to not get different behaviour on Maven 3 (4.0.0 model) and Maven 4 (4.1.0). |
|
The generation of a consumer POM derived from the project POM is fully in Maven core, which is the reason for this pull request. The POM files generated by pull request 508 are different: they are not derived from a project's POM. Instead, they are derived from The generation of POM files derived from Since the Maven JAR Plugin needs to analyse the Maven Compiler Plugin output for dispatching it in different modules, it has information that Maven core does not have easily. Therefore, Maven JAR Plugin is a good place for generating POM derived from module-info, while Maven core is fully in charge of generating POM derived from project POM. |
…lass that we can reuse in other packages.
…ndencies> elements.
8e867a6 to
52fc26b
Compare
|
Maven 4 automatically generates a consumer POM after a successful build. This consumer POM already excludes some elements from the original POM such as the list of sub-projects. However, when building a modular project (in Java sense), there are two more elements that need to be excluded:
<build>because it contains (in the modular case) the<sources>element which is not compatible with the Maven 4.0.0 model. This pull request removes the full<build>element instead of only the<sources>child element because the build configuration is invalid without the sources, and I think that information about how the project was built is not really necessary for consumers anyway.<dependencies>because the effective dependencies will be dispatched in the POM files generated bymaven-jar-pluginfor each Java module from the content ofmodule-info.class.