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

slawekjaranowski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-dependency-plugin.git


The following commit(s) were added to refs/heads/master by this push:
     new fdd2b51b [#1637] Fix dependency:add routing versioned deps into 
dependencyManagement
fdd2b51b is described below

commit fdd2b51b3af56946be2d67a91d21b4430fc9b51c
Author: Bruno Borges <[email protected]>
AuthorDate: Fri May 29 16:44:39 2026 -0400

    [#1637] Fix dependency:add routing versioned deps into dependencyManagement
    
    The `dependency:add` goal incorrectly added a versioned dependency to the
    current POM's <dependencyManagement> instead of <dependencies> when the
    project's existing dependencies are version-less because their versions come
    from a BOM import (the standard maven-archetype-quickstart layout).
    
    With align=true (default), detectConventions() set useManaged=true purely
    because most <dependencies> were version-less, even though no parent POM
    existed to host the managed entry. The result was written to the current
    POM's <dependencyManagement>, which contradicts the documented behavior of
    the `align` parameter ("add managed dependency to parent POM") and means the
    dependency was never actually added to the project.
    
    The auto-detected useManaged convention now only applies when a separate
    parent POM exists to host the managed dependency. For a single/leaf POM a
    versioned add goes to <dependencies>. Explicit -Dmanaged=true is unchanged.
    
    Adds an integration test (add-dependency/bom-import) reproducing the case.
    
    Co-authored-by: Copilot <[email protected]>
---
 .../add-dependency/bom-import/invoker.properties   | 18 ++++++++
 src/it/projects/add-dependency/bom-import/pom.xml  | 54 ++++++++++++++++++++++
 .../add-dependency/bom-import/verify.groovy        | 33 +++++++++++++
 .../plugins/dependency/AddDependencyMojo.java      | 17 ++++---
 4 files changed, 116 insertions(+), 6 deletions(-)

diff --git a/src/it/projects/add-dependency/bom-import/invoker.properties 
b/src/it/projects/add-dependency/bom-import/invoker.properties
new file mode 100644
index 00000000..4929f287
--- /dev/null
+++ b/src/it/projects/add-dependency/bom-import/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals = 
${project.groupId}:${project.artifactId}:${project.version}:add 
-Dgav=org.apache.maven.its.dependency:a1:1.0.0
diff --git a/src/it/projects/add-dependency/bom-import/pom.xml 
b/src/it/projects/add-dependency/bom-import/pom.xml
new file mode 100644
index 00000000..c8319d04
--- /dev/null
+++ b/src/it/projects/add-dependency/bom-import/pom.xml
@@ -0,0 +1,54 @@
+<?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>test</groupId>
+    <artifactId>add-dependency-bom-import</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.junit</groupId>
+                <artifactId>junit-bom</artifactId>
+                <version>5.11.0</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/src/it/projects/add-dependency/bom-import/verify.groovy 
b/src/it/projects/add-dependency/bom-import/verify.groovy
new file mode 100644
index 00000000..d3a58aec
--- /dev/null
+++ b/src/it/projects/add-dependency/bom-import/verify.groovy
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+// A single, leaf POM whose existing dependencies are version-less because 
their
+// versions come from a BOM import in <dependencyManagement>. A versioned add 
must
+// land in <dependencies> (not be redirected into this POM's 
<dependencyManagement>).
+File pom = new File(basedir, "pom.xml")
+assert pom.exists()
+def xml = new groovy.xml.XmlSlurper().parseText(pom.text)
+
+def dep = xml.dependencies.dependency.find { it.artifactId.text() == 'a1' }
+assert dep != null : "a1 should be added to <dependencies>"
+assert dep.groupId.text() == 'org.apache.maven.its.dependency'
+assert dep.version.text() == '1.0.0'
+
+def managed = xml.dependencyManagement.dependencies.dependency.find { 
it.artifactId.text() == 'a1' }
+assert managed == null || managed.size() == 0 : "a1 must NOT be added to 
<dependencyManagement>"
diff --git 
a/src/main/java/org/apache/maven/plugins/dependency/AddDependencyMojo.java 
b/src/main/java/org/apache/maven/plugins/dependency/AddDependencyMojo.java
index 0aec3fcb..bfdb7274 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/AddDependencyMojo.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/AddDependencyMojo.java
@@ -642,20 +642,25 @@ public class AddDependencyMojo extends 
AbstractDependencyMojo {
         try {
             PomEditor editor = loadPomEditor(pomFile);
 
+            // Find the parent POM that declares <dependencyManagement>, if 
any.
+            conv.managedPomFile = findManagedDepsPom(project);
+
             // Analyze managed dependency usage: count deps with/without 
version
             long totalDeps = getDependencyCount(editor, false);
             List<String> depVersions = getDependencyVersions(editor, false);
             long depsWithVersion = depVersions.size();
 
-            if (totalDeps > 0 && depsWithVersion < totalDeps / 2.0) {
-                // Majority of deps are version-less → use managed deps
+            // Only treat version-less dependencies as a "managed" convention 
when there is a
+            // separate parent POM to host the managed dependency. Otherwise 
(e.g. a single,
+            // leaf POM whose dependency versions come from a local BOM 
import), a versioned add
+            // belongs in <dependencies>, not in this POM's 
<dependencyManagement>.
+            if (conv.managedPomFile != null && totalDeps > 0 && 
depsWithVersion < totalDeps / 2.0) {
+                // Majority of deps are version-less and a parent manages 
versions → use managed deps
                 conv.useManaged = true;
-                getLog().debug("Convention detected: majority of dependencies 
are version-less (useManaged=true)");
+                getLog().debug("Convention detected: majority of dependencies 
are version-less"
+                        + " and a parent POM manages versions 
(useManaged=true)");
             }
 
-            // Find the POM that has <dependencyManagement>
-            conv.managedPomFile = findManagedDepsPom(project);
-
             // Analyze property patterns from child POM versions
             List<String> allVersions = new java.util.ArrayList<>(depVersions);
             allVersions.addAll(getDependencyVersions(editor, true));

Reply via email to