From b66fe9e414df25c8009e80c8bc386a5f44579cc0 Mon Sep 17 00:00:00 2001 From: Tamas Cservenak Date: Wed, 1 Mar 2023 08:46:39 +0100 Subject: [PATCH] [MRESOLVER-333] Better errors about artifact availability (#261) Users get confused about artifact availability checks, and resolver should provide better error messages. Availability check is checking for (known) origin of locally cached artifact and the request repositories overlap, if none found, the artifact, despite being present locally, is not available. Present this to end users, and educate them what is and what for is "artifact availability check". --- https://issues.apache.org/jira/browse/MRESOLVER-333 --- .../ArtifactResolutionException.java | 25 +++++++++++-------- .../aether/resolution/ArtifactResult.java | 23 +++++++++++++++++ .../impl/DefaultArtifactResolver.java | 6 ++++- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java index 2d829e18f..887a242c4 100644 --- a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResolutionException.java @@ -22,6 +22,7 @@ import java.util.List; import org.eclipse.aether.RepositoryException; +import org.eclipse.aether.repository.LocalArtifactResult; import org.eclipse.aether.transfer.ArtifactNotFoundException; import org.eclipse.aether.transfer.RepositoryOfflineException; @@ -90,27 +91,31 @@ private static String getMessage(List results) { buffer.append("The following artifacts could not be resolved: "); - int unresolved = 0; - String sep = ""; for (ArtifactResult result : results) { if (!result.isResolved()) { - unresolved++; - buffer.append(sep); buffer.append(result.getRequest().getArtifact()); + LocalArtifactResult localResult = result.getLocalArtifactResult(); + if (localResult != null) { + buffer.append(" ("); + if (localResult.getFile() != null) { + buffer.append("present"); + if (!localResult.isAvailable()) { + buffer.append(", but unavailable"); + } + } else { + buffer.append("absent"); + } + buffer.append(")"); + } sep = ", "; } } Throwable cause = getCause(results); if (cause != null) { - if (unresolved == 1) { - buffer.setLength(0); - buffer.append(cause.getMessage()); - } else { - buffer.append(": ").append(cause.getMessage()); - } + buffer.append(": ").append(cause.getMessage()); } return buffer.toString(); diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java index f69dfb7ec..2e93a5379 100644 --- a/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/resolution/ArtifactResult.java @@ -25,6 +25,7 @@ import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.repository.ArtifactRepository; +import org.eclipse.aether.repository.LocalArtifactResult; import org.eclipse.aether.transfer.ArtifactNotFoundException; import static java.util.Objects.requireNonNull; @@ -45,6 +46,8 @@ public final class ArtifactResult { private ArtifactRepository repository; + private LocalArtifactResult localArtifactResult; + /** * Creates a new result for the specified request. * @@ -134,6 +137,26 @@ public ArtifactResult setRepository(ArtifactRepository repository) { return this; } + /** + * Gets the {@link LocalArtifactResult} received during artifact resolution. + * + * @return The {@link LocalArtifactResult} or {@code null}. + * @since 1.9.6 + */ + public LocalArtifactResult getLocalArtifactResult() { + return localArtifactResult; + } + + /** + * Sets the {@link LocalArtifactResult} that is received during artifact resolution. + * + * @param localArtifactResult The local artifact result. + * @since 1.9.6 + */ + public void setLocalArtifactResult(LocalArtifactResult localArtifactResult) { + this.localArtifactResult = localArtifactResult; + } + /** * Indicates whether the requested artifact was resolved. Note that the artifact might have been successfully * resolved despite {@link #getExceptions()} indicating transfer errors while trying to fetch the artifact from some diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java index 58b4a31a2..c27bd996d 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java @@ -350,6 +350,7 @@ private List resolve( LocalArtifactResult local = lrm.find( session, new LocalArtifactRequest(artifact, filteredRemoteRepositories, request.getRequestContext())); + result.setLocalArtifactResult(local); boolean found = (filter != null && local.isAvailable()) || isLocallyInstalled(local, versionResult); // with filtering it is availability that drives logic // without filtering it is simply presence of file that drives the logic @@ -382,7 +383,10 @@ private List resolve( } if (local.getFile() != null) { - LOGGER.debug("Verifying availability of {} from {}", local.getFile(), remoteRepositories); + LOGGER.info( + "Artifact {} is present in the local repository, but cached from a remote repository ID that is unavailable in current build context, verifying that is downloadable from {}", + artifact, + remoteRepositories); } LOGGER.debug("Resolving artifact {} from {}", artifact, remoteRepositories);