This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/master by this push:
new cc0e5d6398 Fix #11715: preserve 4.1.0 namespace/schema in
help:effective-pom (#11742)
cc0e5d6398 is described below
commit cc0e5d63985ba1413a3c83fb68e1df6790d2518b
Author: Arturo Bernal <[email protected]>
AuthorDate: Sat Jun 13 09:57:41 2026 +0200
Fix #11715: preserve 4.1.0 namespace/schema in help:effective-pom (#11742)
* Fix #11715: preserve 4.1.0 namespace/schema in help:effective-pom
When generating the effective POM for a modelVersion 4.1.0 project,
preserve the root <project> namespace and schemaLocation as 4.1.0
instead of falling back to 4.0.0.
Add/keep coverage with MavenITgh11715EffectivePomNamespaceTest to
verify the effective POM header contains:
- xmlns http://maven.apache.org/POM/4.1.0
- schemaLocation .../maven-4.1.0.xsd
* Extract XmlService classloader fix and use MavenModelVersion
- Remove XmlService classloader fallback (extracted to PR #12237)
- Use MavenModelVersion to compute the minimum model version
instead of hardcoding 4.0.0 as the fallback
- Align namespace/schemaLocation format strings with
TransformerSupport conventions
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* Remove super(versionRange) call — AbstractMavenIntegrationTestCase has no
String constructor
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* Use declared modelVersion for namespace, fall back to MavenModelVersion
MavenModelVersion computes the minimum required version based on
features, but help:effective-pom should preserve the version declared
in the POM. Use model.getModelVersion() first and only fall back to
MavenModelVersion when the version is not explicitly set.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Guillaume Nodet <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
---
.../maven/model/io/xpp3/MavenXpp3Writer.java | 16 ++++++++
.../java/org/apache/maven/model/ModelTest.java | 41 ++++++++++++++++++
.../MavenITgh11715EffectivePomNamespaceTest.java | 48 ++++++++++++++++++++++
.../src/test/resources/gh-11715/pom.xml | 10 +++++
4 files changed, 115 insertions(+)
diff --git
a/compat/maven-model/src/main/java/org/apache/maven/model/io/xpp3/MavenXpp3Writer.java
b/compat/maven-model/src/main/java/org/apache/maven/model/io/xpp3/MavenXpp3Writer.java
index 66328256d9..8b76369f5d 100644
---
a/compat/maven-model/src/main/java/org/apache/maven/model/io/xpp3/MavenXpp3Writer.java
+++
b/compat/maven-model/src/main/java/org/apache/maven/model/io/xpp3/MavenXpp3Writer.java
@@ -26,6 +26,7 @@
import org.apache.maven.model.InputLocation;
import org.apache.maven.model.Model;
+import org.apache.maven.model.v4.MavenModelVersion;
import org.apache.maven.model.v4.MavenStaxWriter;
/**
@@ -33,6 +34,10 @@
*/
@Deprecated
public class MavenXpp3Writer {
+ private static final String NAMESPACE_FORMAT =
"http://maven.apache.org/POM/%s";
+
+ private static final String SCHEMA_LOCATION_FORMAT =
"https://maven.apache.org/xsd/maven-%s.xsd";
+
// --------------------------/
// - Class/Member Variables -/
// --------------------------/
@@ -79,6 +84,7 @@ public void setStringFormatter(InputLocation.StringFormatter
stringFormatter) {
*/
public void write(Writer writer, Model model) throws IOException {
try {
+ configureDelegate(model);
delegate.write(writer, model.getDelegate());
} catch (XMLStreamException e) {
throw new IOException(e);
@@ -94,9 +100,19 @@ public void write(Writer writer, Model model) throws
IOException {
*/
public void write(OutputStream stream, Model model) throws IOException {
try {
+ configureDelegate(model);
delegate.write(stream, model.getDelegate());
} catch (XMLStreamException e) {
throw new IOException(e);
}
} // -- void write( OutputStream, Model )
+
+ private void configureDelegate(Model model) {
+ String version = model.getModelVersion();
+ if (version == null || version.isBlank()) {
+ version = new
MavenModelVersion().getModelVersion(model.getDelegate());
+ }
+ delegate.setNamespace(String.format(NAMESPACE_FORMAT, version));
+ delegate.setSchemaLocation(String.format(SCHEMA_LOCATION_FORMAT,
version));
+ }
}
diff --git
a/compat/maven-model/src/test/java/org/apache/maven/model/ModelTest.java
b/compat/maven-model/src/test/java/org/apache/maven/model/ModelTest.java
index 967af237c5..652ff95354 100644
--- a/compat/maven-model/src/test/java/org/apache/maven/model/ModelTest.java
+++ b/compat/maven-model/src/test/java/org/apache/maven/model/ModelTest.java
@@ -18,12 +18,16 @@
*/
package org.apache.maven.model;
+import java.io.StringWriter;
+
+import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Tests {@code Model}.
@@ -67,6 +71,43 @@ void testToStringNullSafe() {
assertNotNull(new Model().toString());
}
+ @Test
+ void testWriteUsesMinimumModelVersionNamespace() throws Exception {
+ Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
+ .modelVersion("4.1.0")
+ .root(true)
+ .groupId("g")
+ .artifactId("a")
+ .version("1")
+ .build());
+
+ StringWriter output = new StringWriter();
+ new MavenXpp3Writer().write(output, model);
+
+ String xml = output.toString();
+
assertTrue(xml.contains("xmlns=\"http://maven.apache.org/POM/4.1.0\""));
+ assertTrue(
+ xml.contains(
+
"xsi:schemaLocation=\"http://maven.apache.org/POM/4.1.0
https://maven.apache.org/xsd/maven-4.1.0.xsd\""));
+ }
+
+ @Test
+ void testWriteDefaultsTo400Namespace() throws Exception {
+ Model model = new Model();
+ model.setGroupId("g");
+ model.setArtifactId("a");
+ model.setVersion("1");
+
+ StringWriter output = new StringWriter();
+ new MavenXpp3Writer().write(output, model);
+
+ String xml = output.toString();
+
assertTrue(xml.contains("xmlns=\"http://maven.apache.org/POM/4.0.0\""));
+ assertTrue(
+ xml.contains(
+
"xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd\""));
+ }
+
@Test
void testPropertiesClear() {
// Test for issue #11552: NullPointerException when clearing properties
diff --git
a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11715EffectivePomNamespaceTest.java
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11715EffectivePomNamespaceTest.java
new file mode 100644
index 0000000000..2a908e09ce
--- /dev/null
+++
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11715EffectivePomNamespaceTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.Path;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * This is a test set for <a
href="https://github.com/apache/maven/issues/11715">GH-11715</a>.
+ *
+ * Verifies that help:effective-pom preserves the 4.1.0 root namespace/schema
for a 4.1.0 POM.
+ *
+ * @since 4.0.0-rc-5
+ */
+class MavenITgh11715EffectivePomNamespaceTest extends
AbstractMavenIntegrationTestCase {
+
+ @Test
+ void testIt() throws Exception {
+ Path basedir =
extractResources("/gh-11715").getAbsoluteFile().toPath();
+
+ Verifier verifier = newVerifier(basedir.toString());
+ verifier.addCliArgument("help:effective-pom");
+ verifier.execute();
+ verifier.verifyErrorFreeLog();
+
+ verifier.verifyTextInLog("<modelVersion>4.1.0</modelVersion>");
+ verifier.verifyTextInLog("<project
xmlns=\"http://maven.apache.org/POM/4.1.0\"");
+ verifier.verifyTextInLog(
+ "xsi:schemaLocation=\"http://maven.apache.org/POM/4.1.0
https://maven.apache.org/xsd/maven-4.1.0.xsd\"");
+ }
+}
diff --git a/its/core-it-suite/src/test/resources/gh-11715/pom.xml
b/its/core-it-suite/src/test/resources/gh-11715/pom.xml
new file mode 100644
index 0000000000..212040f339
--- /dev/null
+++ b/its/core-it-suite/src/test/resources/gh-11715/pom.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://maven.apache.org/POM/4.1.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.1.0
https://maven.apache.org/xsd/maven-4.1.0.xsd">
+ <modelVersion>4.1.0</modelVersion>
+ <groupId>org.apache.maven.its.gh11715</groupId>
+ <artifactId>effective-pom-namespace</artifactId>
+ <version>1.0.0</version>
+ <packaging>pom</packaging>
+</project>