You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sl...@apache.org on 2026/08/22 14:52:56 UTC
(maven-resolver-ant-tasks) 01/06: Derive POM dependencies through Maven's own descriptor delegate
This is an automated email from the ASF dual-hosted git repository.
slachiewicz pushed a commit to branch pom-conversion-parity
in repository https://gitbox.apache.org/repos/asf/maven-resolver-ant-tasks.git
commit 91bba793a70cdd917bede351a5551fee21a4cf87
Author: Sylwester Lachiewicz <sl...@apache.org>
AuthorDate: Sat Aug 22 16:43:27 2026 +0200
Derive POM dependencies through Maven's own descriptor delegate
The hand-written model-to-CollectRequest conversion had drifted from
ArtifactDescriptorReaderDelegate, the code Maven runs for the same job:
it pinned optional to false instead of carrying the model's tri-state
value, so dependency management could no longer manage optionality.
Do not restore the local conversion to fix a single field. Delegating
keeps the two in step for every field, now and later.
The POM repositories the delegate collects are deliberately not applied
here; that is a behaviour change and comes separately.
---
.../maven/resolver/internal/ant/AntRepoSys.java | 65 ++++------------
.../resolver/internal/ant/ConverterUtils.java | 87 +++++++++++++++++++---
2 files changed, 91 insertions(+), 61 deletions(-)
diff --git a/src/main/java/org/apache/maven/resolver/internal/ant/AntRepoSys.java b/src/main/java/org/apache/maven/resolver/internal/ant/AntRepoSys.java
index fa31322..a72ffea 100644
--- a/src/main/java/org/apache/maven/resolver/internal/ant/AntRepoSys.java
+++ b/src/main/java/org/apache/maven/resolver/internal/ant/AntRepoSys.java
@@ -95,6 +95,7 @@ import org.eclipse.aether.installation.InstallationException;
import org.eclipse.aether.repository.AuthenticationSelector;
import org.eclipse.aether.repository.MirrorSelector;
import org.eclipse.aether.repository.ProxySelector;
+import org.eclipse.aether.resolution.ArtifactDescriptorResult;
import org.eclipse.aether.supplier.RepositorySystemSupplier;
import org.eclipse.aether.supplier.SessionBuilderSupplier;
import org.eclipse.aether.util.repository.AuthenticationBuilder;
@@ -782,7 +783,7 @@ public class AntRepoSys {
for (DependencyContainer container : dependencies.getDependencyContainers()) {
if (container instanceof Dependency) {
Dependency dep = (Dependency) container;
- ids.add(dep.getVersionlessKey());
+ ids.add(ConverterUtils.versionlessKey(dep, session));
collectRequest.addDependency(ConverterUtils.toDependency(dep, globalExclusions, session));
} else {
populateCollectRequest(collectRequest, task, session, (Dependencies) container, globalExclusions);
@@ -791,69 +792,31 @@ public class AntRepoSys {
if (dependencies.getPom() != null) {
Model model = dependencies.getPom().getModel(task);
- if (model.getDependencyManagement() != null) {
- for (org.apache.maven.model.Dependency manDep :
- model.getDependencyManagement().getDependencies()) {
- Dependency dependency = new Dependency();
- dependency.setArtifactId(manDep.getArtifactId());
- dependency.setClassifier(manDep.getClassifier());
- dependency.setGroupId(manDep.getGroupId());
- dependency.setScope(manDep.getScope());
- dependency.setType(manDep.getType());
- dependency.setVersion(manDep.getVersion());
- if (manDep.getSystemPath() != null
- && !manDep.getSystemPath().isEmpty()) {
- dependency.setSystemPath(task.getProject().resolveFile(manDep.getSystemPath()));
- }
- for (org.apache.maven.model.Exclusion exc : manDep.getExclusions()) {
- Exclusion exclusion = new Exclusion();
- exclusion.setGroupId(exc.getGroupId());
- exclusion.setArtifactId(exc.getArtifactId());
- exclusion.setClassifier("*");
- exclusion.setExtension("*");
- dependency.addExclusion(exclusion);
- }
- collectRequest.addManagedDependency(
- ConverterUtils.toManagedDependency(dependency, globalExclusions, session));
- }
+ ArtifactDescriptorResult descriptor = ConverterUtils.toArtifactDescriptor(session, model);
+
+ for (org.eclipse.aether.graph.Dependency managedDependency : descriptor.getManagedDependencies()) {
+ collectRequest.addManagedDependency(ConverterUtils.addExclusions(managedDependency, globalExclusions));
}
- for (org.apache.maven.model.Dependency dep : model.getDependencies()) {
- Dependency dependency = new Dependency();
- dependency.setArtifactId(dep.getArtifactId());
- dependency.setClassifier(dep.getClassifier());
- dependency.setGroupId(dep.getGroupId());
- dependency.setScope(dep.getScope());
- dependency.setType(dep.getType());
- dependency.setVersion(dep.getVersion());
- if (ids.contains(dependency.getVersionlessKey())) {
+ for (org.eclipse.aether.graph.Dependency dependency : descriptor.getDependencies()) {
+ String key = ConverterUtils.versionlessKey(dependency.getArtifact());
+ if (ids.contains(key)) {
project.log(
- "Ignoring dependency " + dependency.getVersionlessKey() + " from " + model.getId()
- + ", already declared locally",
+ "Ignoring dependency " + key + " from " + model.getId() + ", already declared locally",
Project.MSG_VERBOSE);
continue;
}
- if (dep.getSystemPath() != null && !dep.getSystemPath().isEmpty()) {
- dependency.setSystemPath(task.getProject().resolveFile(dep.getSystemPath()));
- }
- for (org.apache.maven.model.Exclusion exc : dep.getExclusions()) {
- Exclusion exclusion = new Exclusion();
- exclusion.setGroupId(exc.getGroupId());
- exclusion.setArtifactId(exc.getArtifactId());
- exclusion.setClassifier("*");
- exclusion.setExtension("*");
- dependency.addExclusion(exclusion);
- }
- collectRequest.addDependency(ConverterUtils.toDependency(dependency, globalExclusions, session));
+ collectRequest.addDependency(ConverterUtils.addExclusions(dependency, globalExclusions));
}
}
if (dependencies.getFile() != null) {
List<Dependency> deps = readDependencies(dependencies.getFile());
for (Dependency dependency : deps) {
- if (ids.contains(dependency.getVersionlessKey())) {
+ String key = ConverterUtils.versionlessKey(dependency, session);
+ if (ids.contains(key)) {
project.log(
- "Ignoring dependency " + dependency.getVersionlessKey() + " from " + dependencies.getFile()
+ "Ignoring dependency " + key + " from " + dependencies.getFile()
+ ", already declared locally",
Project.MSG_VERBOSE);
continue;
diff --git a/src/main/java/org/apache/maven/resolver/internal/ant/ConverterUtils.java b/src/main/java/org/apache/maven/resolver/internal/ant/ConverterUtils.java
index 8bf627d..265948b 100644
--- a/src/main/java/org/apache/maven/resolver/internal/ant/ConverterUtils.java
+++ b/src/main/java/org/apache/maven/resolver/internal/ant/ConverterUtils.java
@@ -26,6 +26,8 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
+import org.apache.maven.model.Model;
+import org.apache.maven.repository.internal.ArtifactDescriptorReaderDelegate;
import org.apache.maven.resolver.internal.ant.types.Authentication;
import org.apache.maven.resolver.internal.ant.types.Dependency;
import org.apache.maven.resolver.internal.ant.types.Exclusion;
@@ -41,6 +43,8 @@ import org.eclipse.aether.artifact.ArtifactTypeRegistry;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.artifact.DefaultArtifactType;
import org.eclipse.aether.repository.RepositoryPolicy;
+import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
+import org.eclipse.aether.resolution.ArtifactDescriptorResult;
import org.eclipse.aether.util.repository.AuthenticationBuilder;
/**
@@ -48,7 +52,7 @@ import org.eclipse.aether.util.repository.AuthenticationBuilder;
*/
class ConverterUtils {
- private static org.eclipse.aether.artifact.Artifact toArtifact(Dependency dependency, ArtifactTypeRegistry types) {
+ static org.eclipse.aether.artifact.Artifact toArtifact(Dependency dependency, ArtifactTypeRegistry types) {
ArtifactType type = types.get(dependency.getType());
if (type == null) {
type = new DefaultArtifactType(dependency.getType());
@@ -70,6 +74,78 @@ class ConverterUtils {
type);
}
+ /**
+ * Converts a Maven {@link Model} into the artifact descriptor that Maven itself would derive from it.
+ * <p>
+ * The conversion is delegated to Maven's own {@link ArtifactDescriptorReaderDelegate}, the code that turns a
+ * model into resolver input during a Maven build, so that a POM contributes the same dependencies, managed
+ * dependencies and repositories here as it does there.
+ *
+ * @param session the repository system session supplying the artifact type registry
+ * @param model the effective model to convert
+ * @return the artifact descriptor derived from the model
+ */
+ public static ArtifactDescriptorResult toArtifactDescriptor(RepositorySystemSession session, Model model) {
+ org.eclipse.aether.artifact.Artifact pomArtifact =
+ new DefaultArtifact(model.getGroupId(), model.getArtifactId(), "pom", model.getVersion());
+ ArtifactDescriptorRequest request = new ArtifactDescriptorRequest();
+ request.setArtifact(pomArtifact);
+ ArtifactDescriptorResult result = new ArtifactDescriptorResult(request);
+ new ArtifactDescriptorReaderDelegate().populateResult(session, result, model);
+ return result;
+ }
+
+ /**
+ * Returns the {@code groupId:artifactId:extension[:classifier]} key of an artifact, used to detect that a POM
+ * dependency is already declared locally.
+ *
+ * @param artifact the artifact to key
+ * @return the versionless key of the artifact
+ */
+ public static String versionlessKey(org.eclipse.aether.artifact.Artifact artifact) {
+ StringBuilder key = new StringBuilder(128);
+ key.append(artifact.getGroupId())
+ .append(':')
+ .append(artifact.getArtifactId())
+ .append(':')
+ .append(artifact.getExtension());
+ if (!artifact.getClassifier().isEmpty()) {
+ key.append(':').append(artifact.getClassifier());
+ }
+ return key.toString();
+ }
+
+ /**
+ * Returns the versionless key of an Ant {@code <dependency>}, normalized the same way as
+ * {@link #versionlessKey(org.eclipse.aether.artifact.Artifact)} so that both can be compared.
+ *
+ * @param dependency the Ant dependency to key
+ * @param session the repository system session supplying the artifact type registry
+ * @return the versionless key of the dependency
+ */
+ public static String versionlessKey(Dependency dependency, RepositorySystemSession session) {
+ return versionlessKey(toArtifact(dependency, session.getArtifactTypeRegistry()));
+ }
+
+ /**
+ * Returns a copy of the dependency with the given exclusions added to the ones it already carries.
+ *
+ * @param dependency the dependency to extend
+ * @param exclusions the exclusions to add, may be empty
+ * @return the dependency with the merged exclusions
+ */
+ public static org.eclipse.aether.graph.Dependency addExclusions(
+ org.eclipse.aether.graph.Dependency dependency, Collection<Exclusion> exclusions) {
+ if (exclusions == null || exclusions.isEmpty()) {
+ return dependency;
+ }
+ Collection<org.eclipse.aether.graph.Exclusion> merged = new LinkedHashSet<>(dependency.getExclusions());
+ for (Exclusion exclusion : exclusions) {
+ merged.add(toExclusion(exclusion));
+ }
+ return dependency.setExclusions(merged);
+ }
+
public static org.eclipse.aether.repository.Authentication toAuthentication(Authentication auth) {
if (auth == null) {
return null;
@@ -90,15 +166,6 @@ class ConverterUtils {
toExclusions(dependency.getExclusions(), exclusions));
}
- public static org.eclipse.aether.graph.Dependency toManagedDependency(
- Dependency dependency, List<Exclusion> exclusions, RepositorySystemSession session) {
- return new org.eclipse.aether.graph.Dependency(
- toArtifact(dependency, session.getArtifactTypeRegistry()),
- dependency.getScope(),
- false,
- toExclusions(dependency.getExclusions(), exclusions));
- }
-
/**
* Converts the given ant repository type to an Aether repository instance with authentication and proxy filled in
* via the sessions' selectors.