Skip to content

Commit

Permalink
#858 Fix module resolution for multi-level projects
Browse files Browse the repository at this point in the history
Modules were processed in a parallel stream which added elements to
an unsynchonized LinkedHashMap / LinkedHashSet.

This may resulted an incomplete set of child modules.

Note that as the stream items are not processed heavily there is no or minor
advantage of parallel processing.
  • Loading branch information
Gabor Garancsi committed Dec 16, 2022
1 parent 23c225f commit e4ee3be
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
Expand Up @@ -1356,7 +1356,7 @@ private static Map<File, Model> getChildModels(Model model, Log logger) throws I

File baseDir = model.getPomFile().getParentFile();

getAllChildModules(model, logger).parallelStream()
getAllChildModules(model, logger).stream()
.map(moduleName -> new File(baseDir, moduleName))
.map(file -> file.isFile() ? file : new File(file, "pom.xml"))
.filter(File::exists)
Expand Down
Expand Up @@ -25,8 +25,16 @@
import java.io.File;
import java.io.StringReader;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.DefaultModelWriter;
import org.apache.maven.model.io.ModelWriter;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.plugin.logging.SystemStreamLog;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
Expand All @@ -49,6 +57,8 @@
* Tests the methods of {@link PomHelper}.
*/
public class PomHelperTest extends AbstractMojoTestCase {
private static final int NUMBER_OF_CHILD_PROJECTS = 30;

@Rule
public MojoRule mojoRule = new MojoRule(this);

Expand Down Expand Up @@ -219,4 +229,50 @@ public void testIssue505ChildModules() throws Exception {
mojoRule.readMavenProject(new File("src/test/resources/org/codehaus/mojo/versions/api/issue-505"));
assertThat(PomHelper.getChildModels(project, new SystemStreamLog()).entrySet(), hasSize(3));
}

@Test
public void testChildModelsForMultiLevelProject() throws Exception {
Path tempDirectory = Files.createTempDirectory("testChildModelsForLargeNumberOfModules");
ModelWriter modelWriter = new DefaultModelWriter();
Map<Path, Model> createdModels = new LinkedHashMap<>();

try {
Model rootProject = createSimpleModel("root");
createdModels.put(tempDirectory, rootProject);
for (int levelOne = 0; levelOne < NUMBER_OF_CHILD_PROJECTS; levelOne++) {
Model levelOneProject = createSimpleModel("child-" + levelOne);
Path levelOneProjectDirectory = tempDirectory.resolve(levelOneProject.getArtifactId());
rootProject.addModule(levelOneProject.getArtifactId());
createdModels.put(levelOneProjectDirectory, levelOneProject);

for (int levelTwo = 0; levelTwo < NUMBER_OF_CHILD_PROJECTS; levelTwo++) {
Model levelTwoProject = createSimpleModel("child-" + levelOne + "-" + levelTwo);
Path levelTwoProjectDirectory = levelOneProjectDirectory.resolve(levelTwoProject.getArtifactId());
levelOneProject.addModule(levelTwoProject.getArtifactId());
createdModels.put(levelTwoProjectDirectory, levelTwoProject);
}
}

for (Map.Entry<Path, Model> entry : createdModels.entrySet()) {
modelWriter.write(entry.getKey().resolve("pom.xml").toFile(), Collections.emptyMap(), entry.getValue());
}

MavenProject project = mojoRule.readMavenProject(tempDirectory.toFile());

assertThat(
PomHelper.getChildModels(project, new SystemStreamLog()).entrySet(), hasSize(createdModels.size()));
} finally {
FileUtils.deleteDirectory(tempDirectory.toFile());
}
}

private Model createSimpleModel(String artifactId) {
Model module = new Model();
module.setGroupId("child.test");
module.setArtifactId(artifactId);
module.setVersion("1.0.0-SNAPSHOT");
module.setPackaging("pom");
module.setModelVersion("4.0.0");
return module;
}
}
Expand Up @@ -367,7 +367,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
}

if ("always".equals(updateBuildOutputTimestampPolicy)) {
reactor.values().parallelStream()
reactor.values().stream()
.map(m -> PomHelper.getModelEntry(reactor, PomHelper.getGroupId(m), PomHelper.getArtifactId(m)))
.filter(Objects::nonNull)
.map(Map.Entry::getValue)
Expand Down

0 comments on commit e4ee3be

Please sign in to comment.