This is an automated email from the ASF dual-hosted git repository.

ascheman 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 67a94a1d92 Avoid IllegalStateException on duplicate profile ids in 
DefaultModelBuilder (#12419)
67a94a1d92 is described below

commit 67a94a1d926ac20e8c563cdbd24c449e5c4aa1e8
Author: Matt Van Horn <[email protected]>
AuthorDate: Sun Jul 19 10:32:21 2026 -0700

    Avoid IllegalStateException on duplicate profile ids in DefaultModelBuilder 
(#12419)
    
    Save/restore profile activations positionally instead of keyed by profile 
id, so POMs with duplicate profile ids (e.g. javafx <=20) no longer crash 
dependency collection. Duplicate-id diagnostics remain with the validator.
    
    Fixes #10209
---
 .../maven/impl/model/DefaultModelBuilder.java      | 15 ++++---
 .../maven/impl/model/DefaultModelBuilderTest.java  | 26 ++++++++++++
 .../poms/factory/duplicate-profile-ids.xml         | 47 ++++++++++++++++++++++
 3 files changed, 80 insertions(+), 8 deletions(-)

diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
index 182d0f1ae8..8a80317e79 100644
--- 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
+++ 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java
@@ -1397,7 +1397,7 @@ Model activateFileModel(Model inputModel) throws 
ModelBuilderException {
             setSource(inputModel);
             inputModel = modelNormalizer.mergeDuplicates(inputModel, request, 
this);
 
-            Map<String, Activation> interpolatedActivations = 
getProfileActivations(inputModel);
+            List<Activation> interpolatedActivations = 
getProfileActivations(inputModel);
             inputModel = injectProfileActivations(inputModel, 
interpolatedActivations);
 
             // profile injection
@@ -2368,20 +2368,19 @@ private DefaultProfileActivationContext 
getProfileActivationContext(ModelBuilder
                 model);
     }
 
-    private Map<String, Activation> getProfileActivations(Model model) {
-        return model.getProfiles().stream()
-                .filter(p -> p.getActivation() != null)
-                .collect(Collectors.toMap(Profile::getId, 
Profile::getActivation));
+    private List<Activation> getProfileActivations(Model model) {
+        return 
model.getProfiles().stream().map(Profile::getActivation).collect(Collectors.toList());
     }
 
-    private Model injectProfileActivations(Model model, Map<String, 
Activation> activations) {
+    private Model injectProfileActivations(Model model, List<Activation> 
activations) {
         List<Profile> profiles = new ArrayList<>();
         boolean modified = false;
-        for (Profile profile : model.getProfiles()) {
+        for (int i = 0; i < model.getProfiles().size(); i++) {
+            Profile profile = model.getProfiles().get(i);
             Activation activation = profile.getActivation();
             if (activation != null) {
                 // restore activation
-                profile = 
profile.withActivation(activations.get(profile.getId()));
+                profile = profile.withActivation(activations.get(i));
                 modified = true;
             }
             profiles.add(profile);
diff --git 
a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelBuilderTest.java
 
b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelBuilderTest.java
index 0789ca89fa..10a1e684df 100644
--- 
a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelBuilderTest.java
+++ 
b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelBuilderTest.java
@@ -29,6 +29,7 @@
 import org.apache.maven.api.Session;
 import org.apache.maven.api.model.Dependency;
 import org.apache.maven.api.model.Model;
+import org.apache.maven.api.model.Profile;
 import org.apache.maven.api.model.Repository;
 import org.apache.maven.api.services.ModelBuilder;
 import org.apache.maven.api.services.ModelBuilderRequest;
@@ -152,6 +153,31 @@ public void testCiFriendlyVersionWithProfiles() {
         assertEquals("0.2.0", result.getEffectiveModel().getVersion());
     }
 
+    @Test
+    public void testDuplicateProfileIdsRetainActivations() {
+        ModelBuilderRequest request = ModelBuilderRequest.builder()
+                .session(session)
+                
.requestType(ModelBuilderRequest.RequestType.CONSUMER_DEPENDENCY)
+                .source(Sources.resolvedSource(
+                        getPom("duplicate-profile-ids"), 
"org.apache.maven.test:duplicate-profile-ids:1.0.0"))
+                .build();
+        ModelBuilderResult result =
+                assertDoesNotThrow(() -> builder.newSession().build(request));
+        assertNotNull(result);
+
+        List<Profile> profiles = result.getEffectiveModel().getProfiles();
+        assertEquals(2, profiles.size());
+        assertEquals("default", profiles.get(0).getId());
+        assertEquals("default", profiles.get(1).getId());
+        assertNotNull(profiles.get(0).getActivation());
+        assertNotNull(profiles.get(1).getActivation());
+        assertTrue(profiles.get(0).getActivation().isActiveByDefault());
+        assertEquals(
+                "duplicate.profile",
+                profiles.get(1).getActivation().getProperty().getName());
+        assertEquals("enabled", 
profiles.get(1).getActivation().getProperty().getValue());
+    }
+
     @Test
     public void testRepositoryUrlInterpolationWithProfiles() {
         // Test case 1: Default properties should be used
diff --git 
a/impl/maven-impl/src/test/resources/poms/factory/duplicate-profile-ids.xml 
b/impl/maven-impl/src/test/resources/poms/factory/duplicate-profile-ids.xml
new file mode 100644
index 0000000000..c70f81e41f
--- /dev/null
+++ b/impl/maven-impl/src/test/resources/poms/factory/duplicate-profile-ids.xml
@@ -0,0 +1,47 @@
+<?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.1.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 
http://maven.apache.org/xsd/maven-4.1.0.xsd";
+         root="true">
+    <modelVersion>4.1.0</modelVersion>
+
+    <groupId>org.apache.maven.test</groupId>
+    <artifactId>duplicate-profile-ids</artifactId>
+    <version>1.0.0</version>
+    <packaging>pom</packaging>
+
+    <profiles>
+        <profile>
+            <id>default</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+        <profile>
+            <id>default</id>
+            <activation>
+                <property>
+                    <name>duplicate.profile</name>
+                    <value>enabled</value>
+                </property>
+            </activation>
+        </profile>
+    </profiles>
+
+</project>

Reply via email to