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>

Reply via email to