Skip to content

Commit 6d2f41a

Browse files
committed
Consumer POM of multi-module project should exclude <build> and <dependencies> elements.
1 parent ee261f7 commit 6d2f41a

File tree

4 files changed

+105
-29
lines changed

4 files changed

+105
-29
lines changed

impl/maven-core/src/main/java/org/apache/maven/internal/transformation/impl/ConsumerPomArtifactTransformer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public void injectTransformedArtifacts(RepositorySystemSession session, MavenPro
9696
}
9797
}
9898

99-
TransformedArtifact createConsumerPomArtifact(
99+
private TransformedArtifact createConsumerPomArtifact(
100100
MavenProject project, Path consumer, RepositorySystemSession session) {
101101
Path actual = project.getFile().toPath();
102102
Path parent = project.getBaseDirectory();

impl/maven-core/src/main/java/org/apache/maven/internal/transformation/impl/DefaultConsumerPomBuilder.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.apache.maven.api.model.DistributionManagement;
3838
import org.apache.maven.api.model.Model;
3939
import org.apache.maven.api.model.ModelBase;
40+
import org.apache.maven.api.model.Parent;
4041
import org.apache.maven.api.model.Profile;
4142
import org.apache.maven.api.model.Repository;
4243
import org.apache.maven.api.model.Scm;
@@ -50,6 +51,7 @@
5051
import org.apache.maven.impl.InternalSession;
5152
import org.apache.maven.model.v4.MavenModelVersion;
5253
import org.apache.maven.project.MavenProject;
54+
import org.apache.maven.project.SourceQueries;
5355
import org.eclipse.aether.RepositorySystemSession;
5456
import org.slf4j.Logger;
5557
import org.slf4j.LoggerFactory;
@@ -342,7 +344,7 @@ static Model transformNonPom(Model model, MavenProject project) {
342344
return model;
343345
}
344346

345-
static Model transformBom(Model model, MavenProject project) {
347+
private static Model transformBom(Model model, MavenProject project) {
346348
boolean preserveModelVersion = model.isPreserveModelVersion();
347349

348350
Model.Builder builder = prune(
@@ -369,19 +371,33 @@ static Model transformPom(Model model, MavenProject project) {
369371

370372
// raw to consumer transform
371373
model = model.withRoot(false).withModules(null).withSubprojects(null);
372-
if (model.getParent() != null) {
373-
model = model.withParent(model.getParent().withRelativePath(null));
374+
Parent parent = model.getParent();
375+
if (parent != null) {
376+
model = model.withParent(parent.withRelativePath(null));
377+
}
378+
var projectSources = project.getBuild().getDelegate().getSources();
379+
if (SourceQueries.usesModuleSourceHierarchy(projectSources)) {
380+
// Dependencies are dispatched by maven-jar-plugin in the POM generated for each module.
381+
model = model.withDependencies(null).withPackaging(POM_PACKAGING);
374382
}
375-
376383
if (!preserveModelVersion) {
384+
/*
385+
* If tne <build> contains <source> elements, it is not compatible with the Maven 4.0.0 model.
386+
* Remove the full <build> element instead of removing only the <sources> element, because the
387+
* build without sources does not mean much. Reminder: this removal can be disabled by setting
388+
* the `preserveModelVersion` XML attribute or `preserve.model.version` property to true.
389+
*/
390+
if (SourceQueries.hasEnabledSources(projectSources)) {
391+
model = model.withBuild(null);
392+
}
377393
model = model.withPreserveModelVersion(false);
378394
String modelVersion = new MavenModelVersion().getModelVersion(model);
379395
model = model.withModelVersion(modelVersion);
380396
}
381397
return model;
382398
}
383399

384-
static void warnNotDowngraded(MavenProject project) {
400+
private static void warnNotDowngraded(MavenProject project) {
385401
LOGGER.warn("The consumer POM for " + project.getId() + " cannot be downgraded to 4.0.0. "
386402
+ "If you intent your build to be consumed with Maven 3 projects, you need to remove "
387403
+ "the features that request a newer model version. If you're fine with having the "

impl/maven-core/src/test/java/org/apache/maven/internal/transformation/impl/ConsumerPomBuilderTest.java

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.junit.jupiter.api.Test;
5252
import org.mockito.Mockito;
5353

54+
import static org.junit.jupiter.api.Assertions.assertFalse;
5455
import static org.junit.jupiter.api.Assertions.assertNotNull;
5556
import static org.junit.jupiter.api.Assertions.assertNull;
5657
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -88,15 +89,22 @@ protected List<Object> getSessionServices() {
8889
return services;
8990
}
9091

91-
@Test
92-
void testTrivialConsumer() throws Exception {
93-
InternalMavenSession.from(InternalSession.from(session))
92+
/**
93+
* Configures {@link #session} with the root directory of a test in {@code src/test/resources/consumer}.
94+
* Returns the request in case the caller wants to apply more configuration.
95+
*/
96+
private MavenExecutionRequest setRootDirectory(String test) {
97+
MavenExecutionRequest request = InternalMavenSession.from(InternalSession.from(session))
9498
.getMavenSession()
95-
.getRequest()
96-
.setRootDirectory(Paths.get("src/test/resources/consumer/trivial"));
97-
98-
Path file = Paths.get("src/test/resources/consumer/trivial/child/pom.xml");
99+
.getRequest();
100+
request.setRootDirectory(Paths.get("src/test/resources/consumer", test));
101+
return request;
102+
}
99103

104+
/**
105+
* Builds the effective model for the given {@code pom.xml} file.
106+
*/
107+
private MavenProject getEffectiveModel(Path file) {
100108
ModelBuilder.ModelBuilderSession mbs = modelBuilder.newSession();
101109
InternalSession.from(session).getData().set(SessionData.key(ModelBuilder.ModelBuilderSession.class), mbs);
102110
Model orgModel = mbs.build(ModelBuilderRequest.builder()
@@ -108,39 +116,50 @@ void testTrivialConsumer() throws Exception {
108116

109117
MavenProject project = new MavenProject(orgModel);
110118
project.setOriginalModel(new org.apache.maven.model.Model(orgModel));
119+
return project;
120+
}
121+
122+
@Test
123+
void testTrivialConsumer() throws Exception {
124+
setRootDirectory("trivial");
125+
Path file = Paths.get("src/test/resources/consumer/trivial/child/pom.xml");
126+
127+
MavenProject project = getEffectiveModel(file);
111128
Model model = builder.build(session, project, Sources.buildSource(file));
112129

113130
assertNotNull(model);
131+
assertNotNull(model.getDependencies());
114132
}
115133

116134
@Test
117135
void testSimpleConsumer() throws Exception {
118-
MavenExecutionRequest request = InternalMavenSession.from(InternalSession.from(session))
119-
.getMavenSession()
120-
.getRequest();
121-
request.setRootDirectory(Paths.get("src/test/resources/consumer/simple"));
136+
MavenExecutionRequest request = setRootDirectory("simple");
122137
request.getUserProperties().setProperty("changelist", "MNG6957");
123-
124138
Path file = Paths.get("src/test/resources/consumer/simple/simple-parent/simple-weather/pom.xml");
125139

126-
ModelBuilder.ModelBuilderSession mbs = modelBuilder.newSession();
127-
InternalSession.from(session).getData().set(SessionData.key(ModelBuilder.ModelBuilderSession.class), mbs);
128-
Model orgModel = mbs.build(ModelBuilderRequest.builder()
129-
.session(InternalSession.from(session))
130-
.source(Sources.buildSource(file))
131-
.requestType(ModelBuilderRequest.RequestType.BUILD_PROJECT)
132-
.build())
133-
.getEffectiveModel();
134-
135-
MavenProject project = new MavenProject(orgModel);
136-
project.setOriginalModel(new org.apache.maven.model.Model(orgModel));
140+
MavenProject project = getEffectiveModel(file);
137141
request.setRootDirectory(Paths.get("src/test/resources/consumer/simple"));
138142
Model model = builder.build(session, project, Sources.buildSource(file));
139143

140144
assertNotNull(model);
145+
assertFalse(model.getDependencies().isEmpty());
141146
assertTrue(model.getProfiles().isEmpty());
142147
}
143148

149+
@Test
150+
void testMultiModuleConsumer() throws Exception {
151+
setRootDirectory("multi-module");
152+
Path file = Paths.get("src/test/resources/consumer/multi-module/pom.xml");
153+
154+
MavenProject project = getEffectiveModel(file);
155+
Model model = builder.build(session, project, Sources.buildSource(file));
156+
157+
assertNotNull(model);
158+
assertNull(model.getBuild());
159+
assertTrue(model.getDependencies().isEmpty());
160+
assertFalse(model.getDependencyManagement().getDependencies().isEmpty());
161+
}
162+
144163
@Test
145164
void testScmInheritance() throws Exception {
146165
Model model = Model.newBuilder()
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<project root="true" xmlns="http://maven.apache.org/POM/4.1.0">
2+
<groupId>org.my.group</groupId>
3+
<artifactId>parent</artifactId>
4+
<version>1.0-SNAPSHOT</version>
5+
<packaging>pom</packaging>
6+
7+
<dependencyManagement>
8+
<dependencies>
9+
<dependency>
10+
<groupId>org.slf4j</groupId>
11+
<artifactId>slf4j-api</artifactId>
12+
<version>2.0.9</version>
13+
</dependency>
14+
</dependencies>
15+
</dependencyManagement>
16+
17+
<dependencies>
18+
<dependency>
19+
<groupId>org.slf4j</groupId>
20+
<artifactId>slf4j-api</artifactId>
21+
</dependency>
22+
<dependency>
23+
<groupId>org.junit.jupiter</groupId>
24+
<artifactId>junit-jupiter-api</artifactId>
25+
<version>5.10.1</version>
26+
<scope>test</scope>
27+
</dependency>
28+
</dependencies>
29+
30+
<build>
31+
<sources>
32+
<source>
33+
<module>org.foo</module>
34+
</source>
35+
<source>
36+
<module>org.foo.bar</module>
37+
</source>
38+
</sources>
39+
</build>
40+
41+
</project>

0 commit comments

Comments
 (0)