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 727d80f6e4 Resolve property before model reflection to avoid recursion 
(#11385, fixes #11384)
727d80f6e4 is described below

commit 727d80f6e457e783d16aae4867317034db7d03d5
Author: Guillaume Nodet <[email protected]>
AuthorDate: Wed Nov 5 13:34:38 2025 +0100

    Resolve property before model reflection to avoid recursion (#11385, fixes 
#11384)
    
    When a POM contains ${project.url} in the <url> field and also defines
    a property named 'project.url', Maven was incorrectly attempting to
    resolve the expression via model reflection first, which would return
    the same ${project.url} value, causing a recursive variable reference
    error.
    
    This fix changes the interpolation resolution order to check model
    properties before prefixed model reflection. This allows properties
    like 'project.url' to be resolved from the <properties> section before
    attempting to use reflection on the model object.
    
    The new resolution order is:
    1. basedir
    2. build.timestamp
    3. user properties
    4. model properties (moved up from position 5)
    5. prefixed model reflection (moved down from position 3)
    6. system properties
    7. environment variables
    8. unprefixed model reflection
    
    This change is consistent with the approach used for MNG-8469, which
    established that explicit property definitions should take precedence
    over model field reflection.
    
    Fixes #11384
---
 .../maven/impl/model/DefaultModelInterpolator.java | 24 +++++-----
 .../impl/model/DefaultModelInterpolatorTest.java   | 20 +++++++++
 ...venITgh11384RecursiveVariableReferenceTest.java | 52 ++++++++++++++++++++++
 .../src/test/resources/gh-11384/pom.xml            | 18 ++++++++
 4 files changed, 103 insertions(+), 11 deletions(-)

diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelInterpolator.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelInterpolator.java
index 6194c1289f..2e8c7b1fe8 100644
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelInterpolator.java
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelInterpolator.java
@@ -179,22 +179,24 @@ String doCallback(
             return new 
MavenBuildTimestamp(request.getSession().getStartTime(), model.getProperties())
                     .formattedTimestamp();
         }
-        // prefixed model reflection
-        for (String prefix : getProjectPrefixes(request)) {
-            if (expression.startsWith(prefix)) {
-                String subExpr = expression.substring(prefix.length());
-                String v = projectProperty(model, projectDir, subExpr, true);
-                if (v != null) {
-                    return v;
-                }
-            }
-        }
         // user properties
         String value = request.getUserProperties().get(expression);
-        // model properties
+        // model properties (check before prefixed model reflection to avoid 
recursion)
         if (value == null) {
             value = model.getProperties().get(expression);
         }
+        // prefixed model reflection
+        if (value == null) {
+            for (String prefix : getProjectPrefixes(request)) {
+                if (expression.startsWith(prefix)) {
+                    String subExpr = expression.substring(prefix.length());
+                    value = projectProperty(model, projectDir, subExpr, true);
+                    if (value != null) {
+                        return value;
+                    }
+                }
+            }
+        }
         // system properties
         if (value == null) {
             value = request.getSystemProperties().get(expression);
diff --git 
a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelInterpolatorTest.java
 
b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelInterpolatorTest.java
index 7afe7a82e2..065bc79ecd 100644
--- 
a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelInterpolatorTest.java
+++ 
b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelInterpolatorTest.java
@@ -575,6 +575,26 @@ void shouldIgnorePropertiesWithPomPrefix() throws 
Exception {
         assertEquals(uninterpolatedName, out.getName());
     }
 
+    @Test
+    void testProjectUrlPropertyDoesNotCauseRecursion() throws Exception {
+        // GH-11384: ${project.url} should resolve to the property 
"project.url" before
+        // trying to resolve via model reflection, which would cause recursion
+        Map<String, String> modelProperties = new HashMap<>();
+        modelProperties.put("project.url", 
"https://github.com/slackapi/java-slack-sdk";);
+
+        Model model = Model.newBuilder()
+                .url("${project.url}")
+                .properties(modelProperties)
+                .build();
+
+        SimpleProblemCollector collector = new SimpleProblemCollector();
+        Model out = interpolator.interpolateModel(
+                model, null, createModelBuildingRequest(context).build(), 
collector);
+
+        assertProblemFree(collector);
+        assertEquals("https://github.com/slackapi/java-slack-sdk";, 
out.getUrl());
+    }
+
     @Provides
     @Priority(10)
     @SuppressWarnings("unused")
diff --git 
a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11384RecursiveVariableReferenceTest.java
 
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11384RecursiveVariableReferenceTest.java
new file mode 100644
index 0000000000..5c60d90820
--- /dev/null
+++ 
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11384RecursiveVariableReferenceTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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/11384";>GH-11384</a>.
+ *
+ * Verifies that ${project.url} can refer to a property named "project.url" 
without causing
+ * a recursive variable reference error. This pattern is used by 
slack-sdk-parent.
+ *
+ * @since 4.0.0-rc-4
+ */
+class MavenITgh11384RecursiveVariableReferenceTest extends 
AbstractMavenIntegrationTestCase {
+
+    /**
+     * Verify that ${project.url} in the url field can reference a property 
named project.url
+     * without causing a recursive variable reference error.
+     */
+    @Test
+    void testIt() throws Exception {
+        Path basedir = 
extractResources("/gh-11384").getAbsoluteFile().toPath();
+
+        Verifier verifier = newVerifier(basedir.toString());
+        verifier.addCliArgument("help:effective-pom");
+        verifier.execute();
+        verifier.verifyErrorFreeLog();
+
+        // Verify that the URL was correctly interpolated from the property
+        
verifier.verifyTextInLog("<url>https://github.com/slackapi/java-slack-sdk</url>");
+    }
+}
+
diff --git a/its/core-it-suite/src/test/resources/gh-11384/pom.xml 
b/its/core-it-suite/src/test/resources/gh-11384/pom.xml
new file mode 100644
index 0000000000..0c23b6b95c
--- /dev/null
+++ b/its/core-it-suite/src/test/resources/gh-11384/pom.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.1.0"; root="true">
+  <groupId>org.apache.maven.its.mng11384</groupId>
+  <artifactId>test</artifactId>
+  <version>1.0</version>
+  <packaging>pom</packaging>
+
+  <name>Maven Integration Test :: GH-11384</name>
+  <description>Test that project.url can refer to a property named project.url 
without causing recursion</description>
+
+  <!-- This pattern is used by slack-sdk-parent and should not cause a 
recursive variable reference error -->
+  <url>${project.url}</url>
+
+  <properties>
+    <project.url>https://github.com/slackapi/java-slack-sdk</project.url>
+  </properties>
+</project>
+

Reply via email to