Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.9.x] [MNG-7720] Wrong build order of forked projects #1038

Merged

Conversation

cstamas
Copy link
Member

@cstamas cstamas commented Mar 7, 2023

The original fix MNG-7672 matched the "scope" but missed the "order". project.collectedProjects are in order as loaded (POM order), is not topologically sorted.

Fix is to use DAG of projects, ask for downstream projects (will return more then we need but sorted) and narrow that list to only contain collected projects.

Related commit: 48cac1c


https://issues.apache.org/jira/browse/MNG-7720

The original fix MNG-7672 matched the "scope" but missed
the "order". project.collectedProjects are in order
as loaded (POM order), is not topologically sorted.

Fix is to use DAG of projects, ask for downstream
projects (will return more then we need but sorted)
and narrow that list to only contain collected
projects.

Related commit: 48cac1c

---

https://issues.apache.org/jira/browse/MNG-7720
return getProjectAndSubModules(project).collect(Collectors.toList());
List<MavenProject> downstreamProjects = session.getProjectDependencyGraph()
.getDownstreamProjects(project, true); // sorted but more than needed
List<MavenProject> collectedProjects = project.getCollectedProjects(); // not sorted but what we need
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be getProjectAndSubModules(project).collect(Collectors.toList()) instead of project.getCollectedProjects(), else the content will be very different.
The first one will return the project and all its submodules (recursively), while the second will just return the modules of the current project.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so only 1 level... right

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would mean we don't need to recurse.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The question is what is expected here? I debugged with Maven SCM and all modules were in that list.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I misread the code at

List<MavenProject> modules = new ArrayList<>();
noErrors = build(results, modules, projectIndex, interimResult.modules, request, profilesXmls, session)
&& noErrors;
projects.addAll(modules);
projects.add(project);

Reading more closely, the projects list will contain all submodules recursively...

private static Stream<MavenProject> getProjectAndSubModules(MavenProject project) {
return Stream.concat(
Stream.of(project),
project.getCollectedProjects().stream().flatMap(LifecycleDependencyResolver::getProjectAndSubModules));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note how this method is recursive...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

We need full subtree from current project, while original
could would go only 1 level deep.
getProjectAndSubModules(project).collect(Collectors.toList()); // not sorted but what we need
return downstreamProjects.stream()
.filter(projectAndSubmodules::contains)
.collect(Collectors.toList()); // sorted what we need
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The returned list should contain the project instance.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can propose the following which may be slightly easier to read

            List<MavenProject> projectAndSubmodules =
                    getProjectAndSubModules(project).collect(Collectors.toList());
            return Stream.concat(
                            Stream.of(project),
                            session.getProjectDependencyGraph().getDownstreamProjects(project, true).stream())
                    .filter(projectAndSubmodules::contains)
                    .collect(Collectors.toList());

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exactly what I figured out yesterday as well

@cstamas cstamas changed the title [MNG-7720] Wrong build order of forked projects [3.9.x] [MNG-7720] Wrong build order of forked projects Mar 7, 2023
@filipelautert
Copy link

Liquibase build started failing when we switcthed to Maven 3.9.0 , it's a similar issue using the aggregate-jar javadoc goal. Here is a failed build link: https://github.com/liquibase/liquibase/actions/runs/4196586092/jobs/7277765171 .
The error occurs in a build were we exclude a submodule (-pl '!liquibase-dist'), and by debugging maven we can see that aggregator was still requesting it causing the null pointer. I also created the following minimal sample project to simulate this error: https://github.com/filipelautert/test-maven-pl-failure .
Anyway, by using Maven with this patch applied it builds again. Thanks for that!

As NOTHING guarantees that none is null, it is really just a "detail"
of current DefaultProjectBuilder code (implementation).
@cstamas cstamas merged commit 57acdd4 into apache:maven-3.9.x Mar 8, 2023
12 checks passed
@cstamas cstamas deleted the maven-3.9.x-MNG-7720-forked-build-order branch March 8, 2023 08:03
@gnodet gnodet mentioned this pull request May 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants