gnodet-bot commented on code in PR #13081:
URL: https://github.com/apache/maven/pull/13081#discussion_r4069495884


##########
impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java:
##########
@@ -2505,21 +2493,115 @@ private DependencyManagement 
loadDependencyManagement(Dependency dependency, Col
                     .build();
         }
 
+        private Model loadImportModel(Dependency dependency, ImportContext 
context) {
+            Collection<String> importIds = context.importIds;
+            String groupId = dependency.getGroupId();
+            String artifactId = dependency.getArtifactId();
+            String version = dependency.getVersion();
+            String imported = groupId + ':' + artifactId + ':' + version;
+
+            if (importIds.contains(imported)) {
+                StringBuilder message = new StringBuilder("The import POMs 
form a cycle: ");
+                for (String modelId : importIds) {
+                    message.append(modelId).append(" -> ");
+                }
+                message.append(imported);
+                if (context.cycleIncludesRelocation(imported)) {
+                    context.reportRelocationProblem(message.toString(), 
dependency.getLocation(""), null);
+                } else {
+                    add(Severity.ERROR, Version.BASE, message.toString());
+                }
+                return null;
+            }
+
+            ImportModelCacheEntry cached =
+                    cache(repositories, groupId, artifactId, version, null, 
IMPORT, ImportModelCacheEntry::new);
+            ImportedModel importedModel = cached.model;
+            if (importedModel == null) {
+                boolean locked = cached.lock.tryLock();
+                if (!locked && context.relocationSources.isEmpty()) {
+                    cached.lock.lock();
+                    locked = true;
+                }
+                try {
+                    importedModel = cached.model;
+                    if (importedModel == null) {
+                        // A relocation may lead back to an import being built 
by another thread.
+                        // Only these paths avoid waiting; ordinary imports 
still share one in-flight build.
+                        importedModel = doLoadDependencyManagement(dependency, 
groupId, artifactId, version, context);
+                        if (locked && importedModel != null) {
+                            cached.model = importedModel;
+                        }
+                    }
+                } finally {
+                    if (locked) {
+                        cached.lock.unlock();
+                    }
+                }
+            }
+            if (importedModel == null) {
+                return null;
+            }
+
+            Model importModel = importedModel.model();
+            Relocation relocation = importModel.getDistributionManagement() != 
null
+                    ? importModel.getDistributionManagement().getRelocation()
+                    : null;
+            if (relocation != null) {
+                if (!validateRelocationCoordinate(relocation.getGroupId(), 
"groupId", dependency, context)
+                        || 
!validateRelocationCoordinate(relocation.getArtifactId(), "artifactId", 
dependency, context)
+                        || 
!validateRelocationCoordinate(relocation.getVersion(), "version", dependency, 
context)) {
+                    return null;
+                }
+                Dependency.Builder relocated = 
Dependency.newBuilder(dependency).version(importedModel.version());
+                if (relocation.getGroupId() != null && 
!relocation.getGroupId().isEmpty()) {
+                    relocated.groupId(relocation.getGroupId());
+                }
+                if (relocation.getArtifactId() != null
+                        && !relocation.getArtifactId().isEmpty()) {
+                    relocated.artifactId(relocation.getArtifactId());
+                }
+                if (relocation.getVersion() != null && 
!relocation.getVersion().isEmpty()) {
+                    relocated.version(relocation.getVersion());
+                }
+                Dependency relocatedDependency = relocated.build();
+                String message = "The import POM " + imported + " has been 
relocated to "
+                        + relocatedDependency.getGroupId() + ':' + 
relocatedDependency.getArtifactId() + ':'
+                        + relocatedDependency.getVersion();
+                if (relocation.getMessage() != null) {
+                    message += ": " + relocation.getMessage();
+                }
+                add(Severity.WARNING, Version.BASE, message, 
dependency.getLocation(""));

Review Comment:
   Same issue as in the compat builder: the WARNING is emitted unconditionally, 
including for transitive relocation hops. `ImportContext.relocationSources` is 
already the right signal — it is non-empty exactly when we are inside a 
transitive hop. Use it.
   
   ```suggestion
                   String message = "The import POM " + imported + " has been 
relocated to "
                           + relocatedDependency.getGroupId() + ':' + 
relocatedDependency.getArtifactId() + ':'
                           + relocatedDependency.getVersion();
                   if (relocation.getMessage() != null) {
                       message += ": " + relocation.getMessage();
                   }
                   // Only warn when actionable: the user declared this import 
directly and can update
                   // the coordinates. Transitive hops (relocationSources 
non-empty) are not actionable
                   // — log at DEBUG to match 
DistributionManagementArtifactRelocationSource behaviour.
                   if (context.relocationSources().isEmpty()) {
                       add(Severity.WARNING, Version.BASE, message, 
dependency.getLocation(""));
                   } else {
                       LOGGER.debug(message);
                   }
   ```



##########
compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java:
##########
@@ -1187,136 +1182,227 @@ private void importDependencyManagement(
 
             it.remove();
 
-            String groupId = dependency.getGroupId();
-            String artifactId = dependency.getArtifactId();
-            String version = dependency.getVersion();
-
-            if (groupId == null || groupId.length() <= 0) {
-                problems.add(new ModelProblemCollectorRequest(Severity.ERROR, 
Version.BASE)
-                        
.setMessage("'dependencyManagement.dependencies.dependency.groupId' for "
-                                + dependency.getManagementKey() + " is 
missing.")
-                        .setLocation(dependency.getLocation("")));
-                continue;
-            }
-            if (artifactId == null || artifactId.length() <= 0) {
-                problems.add(new ModelProblemCollectorRequest(Severity.ERROR, 
Version.BASE)
-                        
.setMessage("'dependencyManagement.dependencies.dependency.artifactId' for "
-                                + dependency.getManagementKey() + " is 
missing.")
-                        .setLocation(dependency.getLocation("")));
-                continue;
-            }
-            if (version == null || version.length() <= 0) {
-                problems.add(new ModelProblemCollectorRequest(Severity.ERROR, 
Version.BASE)
-                        
.setMessage("'dependencyManagement.dependencies.dependency.version' for "
-                                + dependency.getManagementKey() + " is 
missing.")
-                        .setLocation(dependency.getLocation("")));
-                continue;
+            DependencyManagement importedManagement =
+                    loadDependencyManagement(dependency, model, request, 
problems, importIds);
+            if (importedManagement != null) {
+                if (importedManagements == null) {
+                    importedManagements = new ArrayList<>();
+                }
+                importedManagements.add(importedManagement);
             }
+        }
 
-            String imported = groupId + ':' + artifactId + ':' + version;
+        importIds.remove(importing);
 
-            if (importIds.contains(imported)) {
-                StringBuilder message =
-                        new StringBuilder("The dependencies of type=pom and 
with scope=import form a cycle: ");
-                for (String modelId : importIds) {
-                    message.append(modelId);
-                    message.append(" -> ");
-                }
-                message.append(imported);
-                problems.add(
-                        new ModelProblemCollectorRequest(Severity.ERROR, 
Version.BASE).setMessage(message.toString()));
+        dependencyManagementImporter.importManagement(model, 
importedManagements, request, problems);
+    }
 
-                continue;
+    private DependencyManagement loadDependencyManagement(
+            Dependency dependency,
+            Model model,
+            ModelBuildingRequest request,
+            DefaultModelProblemCollector problems,
+            Collection<String> importIds) {
+        String groupId = dependency.getGroupId();
+        String artifactId = dependency.getArtifactId();
+        String version = dependency.getVersion();
+
+        if (groupId == null || groupId.length() <= 0) {
+            problems.add(new ModelProblemCollectorRequest(Severity.ERROR, 
Version.BASE)
+                    
.setMessage("'dependencyManagement.dependencies.dependency.groupId' for "
+                            + dependency.getManagementKey() + " is missing.")
+                    .setLocation(dependency.getLocation("")));
+            return null;
+        }
+        if (artifactId == null || artifactId.length() <= 0) {
+            problems.add(new ModelProblemCollectorRequest(Severity.ERROR, 
Version.BASE)
+                    
.setMessage("'dependencyManagement.dependencies.dependency.artifactId' for "
+                            + dependency.getManagementKey() + " is missing.")
+                    .setLocation(dependency.getLocation("")));
+            return null;
+        }
+        if (version == null || version.length() <= 0) {
+            problems.add(new ModelProblemCollectorRequest(Severity.ERROR, 
Version.BASE)
+                    
.setMessage("'dependencyManagement.dependencies.dependency.version' for "
+                            + dependency.getManagementKey() + " is missing.")
+                    .setLocation(dependency.getLocation("")));
+            return null;
+        }
+
+        String imported = groupId + ':' + artifactId + ':' + version;
+
+        if (importIds.contains(imported)) {
+            StringBuilder message = new StringBuilder("The import POMs form a 
cycle: ");
+            for (String modelId : importIds) {
+                message.append(modelId);
+                message.append(" -> ");
             }
+            message.append(imported);
+            problems.add(new ModelProblemCollectorRequest(Severity.ERROR, 
Version.BASE).setMessage(message.toString()));
+
+            return null;
+        }
 
-            DependencyManagement importMgmt =
-                    getCache(request.getModelCache(), groupId, artifactId, 
version, ModelCacheTag.IMPORT);
+        DependencyManagement importedManagement =
+                getCache(request.getModelCache(), groupId, artifactId, 
version, ModelCacheTag.IMPORT);
 
-            if (importMgmt == null) {
-                if (workspaceResolver == null && modelResolver == null) {
-                    throw new NullPointerException(String.format(
-                            "request.workspaceModelResolver and 
request.modelResolver cannot be null"
-                                    + " (parent POM %s and POM %s)",
-                            ModelProblemUtils.toId(groupId, artifactId, 
version),
-                            ModelProblemUtils.toSourceHint(model)));
-                }
+        if (importedManagement == null) {
+            Model importModel = resolveImportModel(dependency, model, request, 
problems, importIds);
+            if (importModel == null) {
+                return null;
+            }
 
-                Model importModel = null;
-                if (workspaceResolver != null) {
-                    try {
-                        importModel = 
workspaceResolver.resolveEffectiveModel(groupId, artifactId, version);
-                    } catch (UnresolvableModelException e) {
-                        problems.add(new 
ModelProblemCollectorRequest(Severity.FATAL, Version.BASE)
-                                .setMessage(e.getMessage())
-                                .setException(e));
-                        continue;
-                    }
+            Relocation relocation = importModel.getDistributionManagement() != 
null
+                    ? importModel.getDistributionManagement().getRelocation()
+                    : null;
+            if (relocation != null) {
+                Dependency relocated = dependency.clone();
+                if (!validateRelocationCoordinate(relocation.getGroupId(), 
"groupId", dependency, problems)
+                        || 
!validateRelocationCoordinate(relocation.getArtifactId(), "artifactId", 
dependency, problems)
+                        || 
!validateRelocationCoordinate(relocation.getVersion(), "version", dependency, 
problems)) {
+                    return null;
                 }
-
-                // no workspace resolver or workspace resolver returned null 
(i.e. model not in workspace)
-                if (importModel == null) {
-                    final ModelSource importSource;
+                if (relocation.getGroupId() != null && 
!relocation.getGroupId().isEmpty()) {
+                    relocated.setGroupId(relocation.getGroupId());
+                }
+                if (relocation.getArtifactId() != null
+                        && !relocation.getArtifactId().isEmpty()) {
+                    relocated.setArtifactId(relocation.getArtifactId());
+                }
+                if (relocation.getVersion() != null && 
!relocation.getVersion().isEmpty()) {
+                    relocated.setVersion(relocation.getVersion());
+                }
+                String message = "The import POM " + imported + " has been 
relocated to " + relocated.getGroupId() + ':'
+                        + relocated.getArtifactId() + ':' + 
relocated.getVersion();
+                if (relocation.getMessage() != null) {
+                    message += ": " + relocation.getMessage();
+                }
+                problems.add(new 
ModelProblemCollectorRequest(Severity.WARNING, Version.BASE)
+                        .setMessage(message)
+                        .setLocation(dependency.getLocation("")));

Review Comment:
   The warning is emitted unconditionally — including for transitive relocation 
hops where the user has nothing to update. Only emit `WARNING` when it is 
actually actionable (direct import). Transitive hops should be `DEBUG`.
   
   `ImportContext` doesn't exist in the compat builder, but you can check 
whether `importIds` is at its initial depth — or simply replicate the 
`relocationSources`-based check. The simplest approach: add a `Logger` field 
and split on whether this is a direct or transitive call.
   
   ```suggestion
                   String message = "The import POM " + imported + " has been 
relocated to " + relocated.getGroupId() + ':'
                           + relocated.getArtifactId() + ':' + 
relocated.getVersion();
                   if (relocation.getMessage() != null) {
                       message += ": " + relocation.getMessage();
                   }
                   // Only warn when the user directly declared this import and 
can act on it.
                   // Transitive relocation hops (a BOM re-importing a 
relocated BOM) are not
                   // actionable by the user — log at DEBUG to match artifact 
relocation behaviour.
                   if (importIds.isEmpty()) {
                       problems.add(new 
ModelProblemCollectorRequest(Severity.WARNING, Version.BASE)
                               .setMessage(message)
                               .setLocation(dependency.getLocation("")));
                   } else {
                       LOGGER.debug(message);
                   }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to