This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch maven-4.0.x
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/maven-4.0.x by this push:
new ba5c9a4ff1 [maven-4.0.x] Fix BOM packaging in consumer POMs (#11427)
(#11464)
ba5c9a4ff1 is described below
commit ba5c9a4ff160a1a354225a1f1ca70225aa857271
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue Nov 18 19:02:40 2025 +0100
[maven-4.0.x] Fix BOM packaging in consumer POMs (#11427) (#11464)
This commit addresses two issues with BOM (Bill of Materials) handling in
consumer POMs:
1. BOM packaging not transformed to POM in consumer POMs:
When a project uses packaging=bom, the consumer POM was incorrectly
retaining this packaging type. Since 'bom' is not a valid packaging
type in Maven 4.0.0 model, this caused errors when the consumer POM
was used. The fix ensures that BOM packaging is always transformed
to 'pom' in consumer POMs, regardless of whether flattening is enabled.
2. Dependency versions preserved in dependencyManagement:
The effective model already contains resolved versions for dependencies
in dependencyManagement sections. The fix ensures these versions are
properly preserved in the consumer POM for both flattened and
non-flattened BOMs.
Changes:
- Modified DefaultConsumerPomBuilder.build() to detect BOMs based on
original packaging and handle them appropriately
- Added buildBomWithoutFlatten() method to handle BOMs when flattening
is disabled, using the raw model but still transforming packaging
- Added integration test to verify both issues are fixed
Fixes issues reported in:
https://lists.apache.org/thread/41q40v598pd8mr32lmgwdfb2xm7lzm6l
(cherry picked from commit 7d6fd870aaa07478705943e00a4d3c770c77eb68)
---
.../impl/DefaultConsumerPomBuilder.java | 25 +++-
.../maven/it/MavenITgh11427BomConsumerPomTest.java | 130 +++++++++++++++++++++
.../gh-11427-bom-consumer-pom/bom/pom.xml | 55 +++++++++
.../gh-11427-bom-consumer-pom/module/pom.xml | 48 ++++++++
.../resources/gh-11427-bom-consumer-pom/pom.xml | 37 ++++++
5 files changed, 291 insertions(+), 4 deletions(-)
diff --git
a/impl/maven-core/src/main/java/org/apache/maven/internal/transformation/impl/DefaultConsumerPomBuilder.java
b/impl/maven-core/src/main/java/org/apache/maven/internal/transformation/impl/DefaultConsumerPomBuilder.java
index 9d92f84828..da8f1e1401 100644
---
a/impl/maven-core/src/main/java/org/apache/maven/internal/transformation/impl/DefaultConsumerPomBuilder.java
+++
b/impl/maven-core/src/main/java/org/apache/maven/internal/transformation/impl/DefaultConsumerPomBuilder.java
@@ -74,18 +74,26 @@ public Model build(RepositorySystemSession session,
MavenProject project, ModelS
throws ModelBuilderException {
Model model = project.getModel().getDelegate();
boolean flattenEnabled =
Features.consumerPomFlatten(session.getConfigProperties());
+ String packaging = model.getPackaging();
+ String originalPackaging = project.getOriginalModel().getPackaging();
+
+ // Check if this is a BOM (original packaging is "bom")
+ boolean isBom = BOM_PACKAGING.equals(originalPackaging);
// Check if consumer POM flattening is disabled
if (!flattenEnabled) {
// When flattening is disabled, treat non-POM projects like parent
POMs
// Apply only basic transformations without flattening dependency
management
- return buildPom(session, project, src);
+ // However, BOMs still need special handling to transform
packaging from "bom" to "pom"
+ if (isBom) {
+ return buildBomWithoutFlatten(session, project, src);
+ } else {
+ return buildPom(session, project, src);
+ }
}
// Default behavior: flatten the consumer POM
- String packaging = model.getPackaging();
- String originalPackaging = project.getOriginalModel().getPackaging();
if (POM_PACKAGING.equals(packaging)) {
- if (BOM_PACKAGING.equals(originalPackaging)) {
+ if (isBom) {
return buildBom(session, project, src);
} else {
return buildPom(session, project, src);
@@ -102,6 +110,15 @@ protected Model buildPom(RepositorySystemSession session,
MavenProject project,
return transformPom(model, project);
}
+ protected Model buildBomWithoutFlatten(RepositorySystemSession session,
MavenProject project, ModelSource src)
+ throws ModelBuilderException {
+ ModelBuilderResult result = buildModel(session, src);
+ Model model = result.getRawModel();
+ // For BOMs without flattening, we just need to transform the
packaging from "bom" to "pom"
+ // but keep everything else from the raw model (including unresolved
versions)
+ return transformBom(model, project);
+ }
+
protected Model buildBom(RepositorySystemSession session, MavenProject
project, ModelSource src)
throws ModelBuilderException {
ModelBuilderResult result = buildModel(session, src);
diff --git
a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11427BomConsumerPomTest.java
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11427BomConsumerPomTest.java
new file mode 100644
index 0000000000..7470206a7b
--- /dev/null
+++
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11427BomConsumerPomTest.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.it;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * This is a test set for BOM consumer POM issues.
+ * Verifies that:
+ * 1. BOM packaging is transformed to POM in consumer POMs (not "bom" which is
invalid in Maven 4.0.0)
+ * 2. Dependency versions are preserved in dependencyManagement when using
flatten=true
+ *
+ * @since 4.0.0
+ */
+class MavenITgh11427BomConsumerPomTest extends
AbstractMavenIntegrationTestCase {
+ MavenITgh11427BomConsumerPomTest() {
+ super("[4.0.0-rc-4,)");
+ }
+
+ /**
+ * Verify BOM consumer POM without flattening has correct packaging.
+ */
+ @Test
+ void testBomConsumerPomWithoutFlatten() throws Exception {
+ Path basedir = extractResources("/gh-11427-bom-consumer-pom")
+ .getAbsoluteFile()
+ .toPath();
+
+ Verifier verifier = newVerifier(basedir.toString());
+ verifier.addCliArguments("install");
+ verifier.execute();
+ verifier.verifyErrorFreeLog();
+
+ Path consumerPomPath = Paths.get(
+ verifier.getArtifactPath("org.apache.maven.its.gh-11427",
"bom", "1.0.0-SNAPSHOT", "pom"));
+
+ assertTrue(Files.exists(consumerPomPath), "consumer pom not found at "
+ consumerPomPath);
+
+ List<String> consumerPomLines;
+ try (Stream<String> lines = Files.lines(consumerPomPath)) {
+ consumerPomLines = lines.toList();
+ }
+
+ // Verify packaging is "pom" not "bom"
+ assertTrue(
+ consumerPomLines.stream().anyMatch(s ->
s.contains("<packaging>pom</packaging>")),
+ "Consumer pom should have <packaging>pom</packaging>");
+ assertFalse(
+ consumerPomLines.stream().anyMatch(s ->
s.contains("<packaging>bom</packaging>")),
+ "Consumer pom should NOT have <packaging>bom</packaging>");
+
+ // Verify dependencyManagement is present
+ assertTrue(
+ consumerPomLines.stream().anyMatch(s ->
s.contains("<dependencyManagement>")),
+ "Consumer pom should have dependencyManagement");
+ }
+
+ /**
+ * Verify BOM consumer POM with flattening has correct packaging and
versions.
+ */
+ @Test
+ void testBomConsumerPomWithFlatten() throws Exception {
+ Path basedir = extractResources("/gh-11427-bom-consumer-pom")
+ .getAbsoluteFile()
+ .toPath();
+
+ Verifier verifier = newVerifier(basedir.toString());
+ verifier.addCliArguments("install",
"-Dmaven.consumer.pom.flatten=true");
+ verifier.execute();
+ verifier.verifyErrorFreeLog();
+
+ Path consumerPomPath = Paths.get(
+ verifier.getArtifactPath("org.apache.maven.its.gh-11427",
"bom", "1.0.0-SNAPSHOT", "pom"));
+
+ assertTrue(Files.exists(consumerPomPath), "consumer pom not found at "
+ consumerPomPath);
+
+ List<String> consumerPomLines;
+ try (Stream<String> lines = Files.lines(consumerPomPath)) {
+ consumerPomLines = lines.toList();
+ }
+
+ // Verify packaging is "pom" not "bom"
+ assertTrue(
+ consumerPomLines.stream().anyMatch(s ->
s.contains("<packaging>pom</packaging>")),
+ "Consumer pom should have <packaging>pom</packaging>");
+ assertFalse(
+ consumerPomLines.stream().anyMatch(s ->
s.contains("<packaging>bom</packaging>")),
+ "Consumer pom should NOT have <packaging>bom</packaging>");
+
+ // Verify dependencyManagement is present
+ assertTrue(
+ consumerPomLines.stream().anyMatch(s ->
s.contains("<dependencyManagement>")),
+ "Consumer pom should have dependencyManagement");
+
+ // Verify versions are present in dependencies
+ String content = String.join("\n", consumerPomLines);
+ assertTrue(
+ content.contains("<version>1.0.0-SNAPSHOT</version>") ||
content.contains("<version>${"),
+ "Consumer pom should have version for module dependency");
+ assertTrue(
+ content.contains("<version>4.13.2</version>"),
+ "Consumer pom should have version for junit dependency");
+ }
+}
+
diff --git
a/its/core-it-suite/src/test/resources/gh-11427-bom-consumer-pom/bom/pom.xml
b/its/core-it-suite/src/test/resources/gh-11427-bom-consumer-pom/bom/pom.xml
new file mode 100644
index 0000000000..8b83130b30
--- /dev/null
+++ b/its/core-it-suite/src/test/resources/gh-11427-bom-consumer-pom/bom/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.gh-11427</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>bom</artifactId>
+ <packaging>bom</packaging>
+
+ <name>GH-11427 BOM</name>
+
+ <properties>
+ <junit.version>4.13.2</junit.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.gh-11427</groupId>
+ <artifactId>module</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
+
diff --git
a/its/core-it-suite/src/test/resources/gh-11427-bom-consumer-pom/module/pom.xml
b/its/core-it-suite/src/test/resources/gh-11427-bom-consumer-pom/module/pom.xml
new file mode 100644
index 0000000000..e90f5c3bb3
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11427-bom-consumer-pom/module/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.gh-11427</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>module</artifactId>
+ <packaging>jar</packaging>
+
+ <name>GH-11427 Module</name>
+
+ <properties>
+ <junit.version>4.13.2</junit.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ </dependency>
+ </dependencies>
+</project>
+
diff --git
a/its/core-it-suite/src/test/resources/gh-11427-bom-consumer-pom/pom.xml
b/its/core-it-suite/src/test/resources/gh-11427-bom-consumer-pom/pom.xml
new file mode 100644
index 0000000000..08d3c3babd
--- /dev/null
+++ b/its/core-it-suite/src/test/resources/gh-11427-bom-consumer-pom/pom.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.gh-11427</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>GH-11427 BOM Consumer POM Test</name>
+
+ <modules>
+ <module>bom</module>
+ <module>module</module>
+ </modules>
+</project>
+