Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.apache.maven.plugin.PluginExecutionException;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingResult;
import org.eclipse.aether.transfer.ArtifactFilteredOutException;

/*

Expand Down Expand Up @@ -177,6 +178,9 @@ private String getReference(Set<Throwable> dejaVu, Throwable exception) {
reference = ConnectException.class.getSimpleName();
}
}
if (findCause(exception, ArtifactFilteredOutException.class) != null) {
reference = "https://maven.apache.org/resolver/remote-repository-filtering.html";
}
} else if (exception instanceof LinkageError) {
reference = LinkageError.class.getSimpleName();
} else if (exception instanceof PluginExecutionException) {
Expand Down Expand Up @@ -207,7 +211,9 @@ private String getReference(Set<Throwable> dejaVu, Throwable exception) {
}
}

if ((reference != null && !reference.isEmpty()) && !reference.startsWith("http:")) {
if ((reference != null && !reference.isEmpty())
&& !reference.startsWith("http:")
&& !reference.startsWith("https:")) {
reference = "http://cwiki.apache.org/confluence/display/MAVEN/" + reference;
}

Expand All @@ -229,6 +235,8 @@ private boolean isNoteworthyException(Throwable exception) {
private String getMessage(String message, Throwable exception) {
String fullMessage = (message != null) ? message : "";

boolean hasArtifactFilteredOut = false;

// To break out of possible endless loop when getCause returns "this", or dejaVu for n-level recursion (n>1)
Set<Throwable> dejaVu = Collections.newSetFromMap(new IdentityHashMap<>());
for (Throwable t = exception; t != null && t != t.getCause(); t = t.getCause()) {
Expand Down Expand Up @@ -260,15 +268,43 @@ private String getMessage(String message, Throwable exception) {
fullMessage = join(fullMessage, exceptionMessage);
}

if (t instanceof ArtifactFilteredOutException) {
hasArtifactFilteredOut = true;
}

if (!dejaVu.add(t)) {
fullMessage = join(fullMessage, "[CIRCULAR REFERENCE]");
break;
}
}

if (hasArtifactFilteredOut) {
fullMessage += System.lineSeparator()
+ System.lineSeparator()
+ "This error indicates that the remote repository's prefix file does not list"
+ " this artifact's group. This commonly happens with repository managers"
+ " using virtual/group repositories that do not properly aggregate prefix files."
+ System.lineSeparator()
+ "To disable prefix-based filtering, add"
+ " -Daether.remoteRepositoryFilter.prefixes=false"
+ " to your command line or to .mvn/maven.config."
+ System.lineSeparator()
+ "See https://maven.apache.org/resolver/remote-repository-filtering.html";
Comment on lines +284 to +292
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be also from GroupId Filter, so we need to use other property aether.remoteRepositoryFilter.groupId=false

}

return fullMessage.trim();
}

private static <T extends Throwable> T findCause(Throwable exception, Class<T> type) {
Set<Throwable> dejaVu = Collections.newSetFromMap(new IdentityHashMap<>());
for (Throwable t = exception; t != null && dejaVu.add(t); t = t.getCause()) {
if (type.isInstance(t)) {
return type.cast(t);
}
}
return null;
}

private String join(String message1, String message2) {
String message = "";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@
import org.apache.maven.plugin.PluginExecutionException;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.transfer.ArtifactFilteredOutException;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
*/
Expand Down Expand Up @@ -124,6 +130,35 @@ public synchronized Throwable getCause() {
assertEquals(expectedReference, summary.getReference());
}

@Test
void testArtifactFilteredOutException() {
RemoteRepository repo =
new RemoteRepository.Builder("my-repo", "default", "https://repo.example.com/maven").build();
ArtifactFilteredOutException filterEx = new ArtifactFilteredOutException(
new DefaultArtifact("com.example:my-lib:jar:1.0"),
repo,
"Prefix com/example/my-lib/1.0/my-lib-1.0.jar NOT allowed from my-repo"
+ " (https://repo.example.com/maven, default, releases)");
ArtifactResult artifactResult = new ArtifactResult(new org.eclipse.aether.resolution.ArtifactRequest(
new DefaultArtifact("com.example:my-lib:jar:1.0"), java.util.List.of(repo), null));
artifactResult.addException(filterEx);
ArtifactResolutionException resolutionEx =
new ArtifactResolutionException(java.util.List.of(artifactResult), "Could not resolve artifact");
MojoExecutionException mojoEx = new MojoExecutionException("Resolution failed", resolutionEx);

DefaultExceptionHandler handler = new DefaultExceptionHandler();
ExceptionSummary summary = handler.handleException(mojoEx);

assertTrue(
summary.getMessage().contains("-Daether.remoteRepositoryFilter.prefixes=false"),
"Message should contain the workaround property");
assertTrue(summary.getMessage().contains("prefix file"), "Message should explain the prefix file cause");
assertEquals(
"https://maven.apache.org/resolver/remote-repository-filtering.html",
summary.getReference(),
"Reference should point to the RRF documentation");
}

@Test
void testHandleExceptionSelfReferencing() {
RuntimeException boom3 = new RuntimeException("BOOM3");
Expand Down