Maven Artifact API provides core interfaces and classes for representing and working with Maven artifacts, including version handling, repository interactions, and metadata management
—
Maven's artifact resolution framework provides exception handling and filtering mechanisms for dependency resolution workflows. This includes a comprehensive exception hierarchy for handling various resolution failures and filtering interfaces for controlling which artifacts are included in resolution processes.
Base class for all artifact resolution exceptions, providing common error information.
public abstract class AbstractArtifactResolutionException extends Exception {
// Artifact information
public Artifact getArtifact();
public String getGroupId();
public String getArtifactId();
public String getVersion();
public String getType();
public String getClassifier();
// Resolution context
public List<ArtifactRepository> getRemoteRepositories();
public String getPath();
public String getOriginalMessage();
// Standard exception methods
public String getMessage();
public String getLocalizedMessage();
}Common Properties:
General artifact resolution problems not covered by more specific exceptions.
public class ArtifactResolutionException extends AbstractArtifactResolutionException {
public ArtifactResolutionException(String message, Artifact artifact);
public ArtifactResolutionException(String message, Artifact artifact,
List<ArtifactRepository> remoteRepositories);
public ArtifactResolutionException(String message, Artifact artifact,
List<ArtifactRepository> remoteRepositories, Throwable cause);
public ArtifactResolutionException(String message, Artifact artifact, Throwable cause);
}Common Scenarios:
Usage Examples:
try {
// Artifact resolution logic
resolveArtifact(artifact);
} catch (ArtifactResolutionException e) {
System.err.println("Failed to resolve: " + e.getArtifact());
System.err.println("Searched repositories: " + e.getRemoteRepositories().size());
System.err.println("Error: " + e.getMessage());
// Handle resolution failure
handleResolutionFailure(e);
}Specific exception for artifacts that cannot be found in any searched repository.
public class ArtifactNotFoundException extends AbstractArtifactResolutionException {
public ArtifactNotFoundException(String message, Artifact artifact);
public ArtifactNotFoundException(String message, Artifact artifact,
List<ArtifactRepository> remoteRepositories);
public ArtifactNotFoundException(String message, Artifact artifact,
List<ArtifactRepository> remoteRepositories, Throwable cause);
public String getDownloadUrl();
}Usage Examples:
try {
artifact = findArtifact(coordinates);
} catch (ArtifactNotFoundException e) {
System.err.println("Artifact not found: " + e.getGroupId() + ":" +
e.getArtifactId() + ":" + e.getVersion());
// Check if download URL is available
String downloadUrl = e.getDownloadUrl();
if (downloadUrl != null) {
System.err.println("Try downloading from: " + downloadUrl);
}
// List searched repositories
for (ArtifactRepository repo : e.getRemoteRepositories()) {
System.err.println("Searched: " + repo.getUrl());
}
}Indicates circular dependencies in the dependency graph.
public class CyclicDependencyException extends ArtifactResolutionException {
public CyclicDependencyException(String message, Artifact artifact);
public CyclicDependencyException(String message, Artifact artifact,
List<ArtifactRepository> remoteRepositories);
public CyclicDependencyException(String message, Artifact artifact,
List<ArtifactRepository> remoteRepositories, Throwable cause);
}Common Scenarios:
Usage Examples:
try {
List<Artifact> resolved = resolveDependencies(rootArtifact);
} catch (CyclicDependencyException e) {
System.err.println("Circular dependency detected:");
System.err.println("Path: " + e.getPath());
System.err.println("Problematic artifact: " + e.getArtifact());
// Attempt to break cycle by excluding optional dependencies
resolveWithExclusions(rootArtifact, e.getArtifact());
}Thrown when multiple artifacts cannot be resolved in a batch operation.
public class MultipleArtifactsNotFoundException extends ArtifactResolutionException {
public MultipleArtifactsNotFoundException(Artifact artifact,
List<Artifact> resolvedArtifacts,
List<Artifact> missingArtifacts,
List<ArtifactRepository> remoteRepositories);
public List<Artifact> getResolvedArtifacts();
public List<Artifact> getMissingArtifacts();
}Usage Examples:
try {
List<Artifact> dependencies = Arrays.asList(dep1, dep2, dep3, dep4);
resolveArtifacts(dependencies);
} catch (MultipleArtifactsNotFoundException e) {
List<Artifact> resolved = e.getResolvedArtifacts();
List<Artifact> missing = e.getMissingArtifacts();
System.out.println("Successfully resolved " + resolved.size() + " artifacts:");
resolved.forEach(a -> System.out.println(" ✓ " + a));
System.out.println("Failed to resolve " + missing.size() + " artifacts:");
missing.forEach(a -> System.out.println(" ✗ " + a));
// Continue with partial resolution or fail completely
if (resolved.size() > missing.size()) {
continueWithPartialDependencies(resolved);
} else {
throw e; // Re-throw if too many failures
}
}Interface for filtering artifacts during resolution processes.
public interface ArtifactFilter {
boolean include(Artifact artifact);
}Usage Examples:
// Filter by scope
ArtifactFilter scopeFilter = new ArtifactFilter() {
@Override
public boolean include(Artifact artifact) {
String scope = artifact.getScope();
return Artifact.SCOPE_COMPILE.equals(scope) ||
Artifact.SCOPE_RUNTIME.equals(scope);
}
};
// Filter by type
ArtifactFilter typeFilter = artifact -> "jar".equals(artifact.getType());
// Filter by group ID pattern
ArtifactFilter groupFilter = artifact ->
artifact.getGroupId().startsWith("com.company.");
// Composite filter (AND logic)
ArtifactFilter compositeFilter = artifact ->
scopeFilter.include(artifact) &&
typeFilter.include(artifact) &&
groupFilter.include(artifact);
// Use filter in resolution
List<Artifact> filtered = dependencies.stream()
.filter(compositeFilter::include)
.collect(Collectors.toList());// Exclude test dependencies
ArtifactFilter excludeTestFilter = artifact ->
!Artifact.SCOPE_TEST.equals(artifact.getScope());
// Include only specific artifact types
ArtifactFilter jarAndWarFilter = artifact -> {
String type = artifact.getType();
return "jar".equals(type) || "war".equals(type);
};
// Exclude snapshot versions
ArtifactFilter excludeSnapshotsFilter = artifact ->
!ArtifactUtils.isSnapshot(artifact.getVersion());
// Include only specific groups
Set<String> allowedGroups = Set.of("org.apache.maven", "junit", "org.slf4j");
ArtifactFilter groupWhitelistFilter = artifact ->
allowedGroups.contains(artifact.getGroupId());
// Exclude artifacts with classifiers
ArtifactFilter noClassifierFilter = artifact ->
artifact.getClassifier() == null || artifact.getClassifier().isEmpty();public void analyzeResolutionException(Exception e) {
if (e instanceof ArtifactNotFoundException) {
ArtifactNotFoundException anfe = (ArtifactNotFoundException) e;
handleMissingArtifact(anfe);
} else if (e instanceof CyclicDependencyException) {
CyclicDependencyException cde = (CyclicDependencyException) e;
handleCircularDependency(cde);
} else if (e instanceof MultipleArtifactsNotFoundException) {
MultipleArtifactsNotFoundException manfe = (MultipleArtifactsNotFoundException) e;
handlePartialResolution(manfe);
} else if (e instanceof OverConstrainedVersionException) {
OverConstrainedVersionException ocve = (OverConstrainedVersionException) e;
handleVersionConflict(ocve);
} else if (e instanceof ArtifactResolutionException) {
ArtifactResolutionException are = (ArtifactResolutionException) e;
handleGeneralResolutionError(are);
}
}// Retry with different repositories
public Artifact resolveWithFallback(Artifact artifact,
List<ArtifactRepository> primaryRepos,
List<ArtifactRepository> fallbackRepos) {
try {
return resolve(artifact, primaryRepos);
} catch (ArtifactNotFoundException e) {
System.out.println("Primary resolution failed, trying fallback repositories...");
return resolve(artifact, fallbackRepos);
}
}
// Resolve with exclusions to break cycles
public List<Artifact> resolveBreakingCycles(Artifact root, Set<Artifact> excludes) {
ArtifactFilter cycleBreaker = artifact -> !excludes.contains(artifact);
return resolveWithFilter(root, cycleBreaker);
}
// Partial resolution for build continuation
public BuildResult continueWithPartialDependencies(List<Artifact> available) {
System.out.println("Continuing build with " + available.size() + " available dependencies");
// Mark missing dependencies for later resolution
// Continue with available artifacts
return buildWithDependencies(available);
}// Comprehensive error reporting
public void reportResolutionFailure(AbstractArtifactResolutionException e) {
System.err.println("=== Artifact Resolution Failure ===");
System.err.println("Artifact: " + formatArtifact(e.getArtifact()));
System.err.println("Error: " + e.getMessage());
if (e.getPath() != null) {
System.err.println("Dependency Path: " + e.getPath());
}
System.err.println("Searched Repositories:");
for (ArtifactRepository repo : e.getRemoteRepositories()) {
System.err.println(" - " + repo.getId() + ": " + repo.getUrl());
}
if (e instanceof ArtifactNotFoundException) {
ArtifactNotFoundException anfe = (ArtifactNotFoundException) e;
if (anfe.getDownloadUrl() != null) {
System.err.println("Suggested download: " + anfe.getDownloadUrl());
}
}
System.err.println("=====================================");
}
private String formatArtifact(Artifact artifact) {
return String.format("%s:%s:%s:%s:%s",
artifact.getGroupId(),
artifact.getArtifactId(),
artifact.getVersion(),
artifact.getType(),
artifact.getClassifier() != null ? artifact.getClassifier() : "");
}// Build resolution filter chain
List<ArtifactFilter> filterChain = Arrays.asList(
excludeTestFilter,
jarAndWarFilter,
excludeSnapshotsFilter,
groupWhitelistFilter
);
// Apply filter chain
ArtifactFilter combinedFilter = artifact ->
filterChain.stream().allMatch(filter -> filter.include(artifact));
// Use in resolution process
public List<Artifact> resolveWithFilters(Artifact root, ArtifactFilter filter) {
List<Artifact> allDependencies = getAllDependencies(root);
return allDependencies.stream()
.filter(filter::include)
.collect(Collectors.toList());
}// Exception wrapping for higher-level APIs
public class BuildException extends Exception {
private final List<AbstractArtifactResolutionException> resolutionFailures;
public BuildException(String message,
List<AbstractArtifactResolutionException> failures) {
super(message);
this.resolutionFailures = failures;
}
public List<AbstractArtifactResolutionException> getResolutionFailures() {
return resolutionFailures;
}
}
// Collect and report all resolution issues
public void buildProject(List<Artifact> dependencies) throws BuildException {
List<AbstractArtifactResolutionException> failures = new ArrayList<>();
for (Artifact dependency : dependencies) {
try {
resolve(dependency);
} catch (AbstractArtifactResolutionException e) {
failures.add(e);
}
}
if (!failures.isEmpty()) {
throw new BuildException("Dependency resolution failed", failures);
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-apache-maven--maven-artifact