CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-apache-maven--maven-artifact

Maven Artifact API provides core interfaces and classes for representing and working with Maven artifacts, including version handling, repository interactions, and metadata management

Pending
Overview
Eval results
Files

resolution.mddocs/

Resolution and Filtering

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.

Resolution Exception Hierarchy

AbstractArtifactResolutionException

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:

  • Artifact: The artifact that failed to resolve
  • Remote Repositories: List of repositories that were searched
  • Path: Dependency path leading to the failed artifact
  • Original Message: Underlying error message

ArtifactResolutionException

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:

  • Repository connectivity issues
  • Corrupted artifact files
  • Permission problems
  • General I/O errors during resolution

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);
}

ArtifactNotFoundException

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());
    }
}

CyclicDependencyException

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:

  • Direct circular dependency: A -> B -> A
  • Indirect circular dependency: A -> B -> C -> A
  • Complex multi-level cycles in large dependency graphs

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());
}

MultipleArtifactsNotFoundException

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
    }
}

Artifact Filtering

ArtifactFilter Interface

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());

Common Filter Implementations

// 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();

Error Handling Strategies

Exception Analysis

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);
    }
}

Recovery Strategies

// 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);
}

Logging and Diagnostics

// 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() : "");
}

Integration with Resolution Workflows

Filter Chain Processing

// 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 Propagation

// 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

docs

index.md

repository.md

resolution.md

versioning.md

tile.json