Skip to content

Commit e3b26d8

Browse files
committed
Fix ReactorReader to prefer consumer POMs over build POMs (apache#11107)
* ReactorReader: prefer consumer POM from project-local repo when resolving POMs When only part of a reactor is built, ReactorReader mirrors artifacts into a project-local repo. If a module depends on another reactor module not in the current session, POM resolution may hit that repo. Today, the main POM path contains the build POM, which can include Maven-4 build-time constructs and be invalid as a repository POM (e.g., missing parent.*). As a result, dependency resolution can fail with fatal model errors. Teach ReactorReader to prefer the consumer POM (classifier=consumer) for POM artifacts when present in the project-local repo, falling back to the main POM otherwise. This avoids consuming a build POM from the project-local repo without changing the repo contents or layout. * Fix ReactorReader to prefer consumer POMs over build POMs When building modules in isolation (outside of the full reactor), the ReactorReader should prefer consumer POMs from the project-local repository over build POMs to avoid invalid POM elements like <parent />. The findModel method now: 1. First checks if the project is in the current reactor session 2. If not found, looks for a consumer POM in the project-local repository 3. Uses the same consumer POM preference logic as findInProjectLocalRepository This eliminates 'invalid POM' warnings when building modules in isolation while maintaining backward compatibility for reactor builds. Fixes apachegh-11084 * Fix (cherry picked from commit 93b85b0)
1 parent 3fc29ff commit e3b26d8

File tree

8 files changed

+219
-0
lines changed

8 files changed

+219
-0
lines changed

impl/maven-core/src/main/java/org/apache/maven/ReactorReader.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,18 @@ private static boolean isTestArtifact(Artifact artifact) {
330330
}
331331

332332
private File findInProjectLocalRepository(Artifact artifact) {
333+
// Prefer the consumer POM when resolving POMs from the project-local repository,
334+
// to avoid treating a build POM as a repository (consumer) POM.
335+
if ("pom".equals(artifact.getExtension())) {
336+
String classifier = artifact.getClassifier();
337+
if (classifier == null || classifier.isEmpty()) {
338+
Path consumer = getArtifactPath(
339+
artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(), "consumer", "pom");
340+
if (Files.isRegularFile(consumer)) {
341+
return consumer.toFile();
342+
}
343+
}
344+
}
333345
Path target = getArtifactPath(artifact);
334346
return Files.isRegularFile(target) ? target.toFile() : null;
335347
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.maven.it;
20+
21+
import java.io.File;
22+
23+
import org.junit.jupiter.api.Test;
24+
25+
/**
26+
* This is a test set for GH-11084.
27+
*/
28+
class MavenITgh11084ReactorReaderPreferConsumerPomTest extends AbstractMavenIntegrationTestCase {
29+
MavenITgh11084ReactorReaderPreferConsumerPomTest() {
30+
super("[4.0.0-rc-2,)");
31+
}
32+
33+
@Test
34+
void partialReactorShouldResolveUsingConsumerPom() throws Exception {
35+
File testDir = extractResources("/gh-11084-reactorreader-prefer-consumer-pom");
36+
37+
// First build module a to populate project-local-repo with artifacts including consumer POM
38+
Verifier v1 = newVerifier(testDir.getAbsolutePath());
39+
v1.addCliArguments("clean", "package", "-X");
40+
v1.setLogFileName("log-1.txt");
41+
v1.execute();
42+
v1.verifyErrorFreeLog();
43+
44+
// Now build only module b; ReactorReader should pick consumer POM from project-local-repo
45+
Verifier v2 = newVerifier(testDir.getAbsolutePath());
46+
v2.setLogFileName("log-2.txt");
47+
v2.addCliArguments("clean", "compile", "-f", "b", "-X");
48+
v2.execute();
49+
v2.verifyErrorFreeLog();
50+
}
51+
}

its/core-it-suite/src/test/java/org/apache/maven/it/TestSuiteOrdering.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public TestSuiteOrdering() {
103103
* the tests are to finishing. Newer tests are also more likely to fail, so this is
104104
* a fail fast technique as well.
105105
*/
106+
suite.addTestSuite(MavenITgh11084ReactorReaderPreferConsumerPomTest.class);
106107
suite.addTestSuite(MavenITgh10312TerminallyDeprecatedMethodInGuiceTest.class);
107108
suite.addTestSuite(MavenITgh10937QuotedPipesInMavenOptsTest.class);
108109
suite.addTestSuite(MavenITgh2532DuplicateDependencyEffectiveModelTest.class);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Licensed to the Apache Software Foundation (ASF) under one
4+
or more contributor license agreements. See the NOTICE file
5+
distributed with this work for additional information
6+
regarding copyright ownership. The ASF licenses this file
7+
to you under the Apache License, Version 2.0 (the
8+
"License"); you may not use this file except in compliance
9+
with the License. You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing,
14+
software distributed under the License is distributed on an
15+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
KIND, either express or implied. See the License for the
17+
specific language governing permissions and limitations
18+
under the License.
19+
-->
20+
<project xmlns="http://maven.apache.org/POM/4.1.0">
21+
<parent />
22+
23+
<artifactId>a</artifactId>
24+
<packaging>jar</packaging>
25+
26+
<dependencies>
27+
<dependency>
28+
<groupId>org.codehaus.plexus</groupId>
29+
<artifactId>plexus-utils</artifactId>
30+
<version>4.0.2</version>
31+
</dependency>
32+
</dependencies>
33+
</project>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package a;
20+
21+
import java.io.IOException;
22+
import java.nio.file.Path;
23+
24+
import org.codehaus.plexus.util.io.CachingOutputStream;
25+
26+
public class A {
27+
public static CachingOutputStream newCachingOutputStream(Path p) throws IOException {
28+
return new CachingOutputStream(p);
29+
}
30+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Licensed to the Apache Software Foundation (ASF) under one
4+
or more contributor license agreements. See the NOTICE file
5+
distributed with this work for additional information
6+
regarding copyright ownership. The ASF licenses this file
7+
to you under the Apache License, Version 2.0 (the
8+
"License"); you may not use this file except in compliance
9+
with the License. You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing,
14+
software distributed under the License is distributed on an
15+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
KIND, either express or implied. See the License for the
17+
specific language governing permissions and limitations
18+
under the License.
19+
-->
20+
<project xmlns="http://maven.apache.org/POM/4.1.0">
21+
22+
<parent />
23+
24+
<artifactId>b</artifactId>
25+
<packaging>jar</packaging>
26+
<dependencies>
27+
<dependency>
28+
<groupId>org.apache.maven.its.gh11084</groupId>
29+
<artifactId>a</artifactId>
30+
</dependency>
31+
</dependencies>
32+
</project>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package b;
20+
21+
import java.nio.file.Paths;
22+
23+
import a.A;
24+
import org.codehaus.plexus.util.io.CachingOutputStream;
25+
26+
public class B {
27+
public static void v() throws Exception {
28+
try (CachingOutputStream is = A.newCachingOutputStream(Paths.get("."))) {}
29+
}
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Licensed to the Apache Software Foundation (ASF) under one
4+
or more contributor license agreements. See the NOTICE file
5+
distributed with this work for additional information
6+
regarding copyright ownership. The ASF licenses this file
7+
to you under the Apache License, Version 2.0 (the
8+
"License"); you may not use this file except in compliance
9+
with the License. You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing,
14+
software distributed under the License is distributed on an
15+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
KIND, either express or implied. See the License for the
17+
specific language governing permissions and limitations
18+
under the License.
19+
-->
20+
<project xmlns="http://maven.apache.org/POM/4.1.0" root="true">
21+
<groupId>org.apache.maven.its.gh11084</groupId>
22+
<artifactId>reactor-root</artifactId>
23+
<version>1.0.0-SNAPSHOT</version>
24+
<packaging>pom</packaging>
25+
26+
<modules>
27+
<module>a</module>
28+
<module>b</module>
29+
</modules>
30+
</project>

0 commit comments

Comments
 (0)