MicroBean Maven CDI

The MicroBean Maven CDI project embeds the Maven machinery responsible for interacting with artifact repositories into your CDI 2.0 environment.

Background and History

The internal Maven machinery for interacting with artifact repositories has gone through several phases of existence.

Its earliest incarnation is in the form of the maven-artifact-resolver artifact, version 1.0, circa 2009 (here in 2017 this artifact should not be used).

This code was subsequently broken out as a standalone project into Sonatype’s Æther project in August 2010.

Sonatype Æther then moved to the Eclipse foundation in August 2014, but never really caught on as a standalone project outside of its original Maven-oriented user base, and was archived in January 2015.

The Sonatype Æther project was handed back to the Maven project and reincarnated as the Maven Artifact Resolver project in January 2017, with an overarching artifact identifier of maven-resolver (not maven-artifact-resolver). Somewhat oddly, the package names have not changed, so the classes provided by the maven-resolver project all start with the org.eclipse.aether. prefix.

This project adapts the maven-resolver project to CDI environments.

Installation

Place this project’s .jar file on your classpath.

How It Works

The maven-resolver project fortunately was written with dependency injection in mind. Specifically, it was written as a Guice module to be used from within Maven proper, which, at least in recent versions, uses Guice under the covers.

It also depends on certain parts of Maven that are expressed as Plexus components. (Plexus was one of the first dependency injection containers and still has its fingerprints in the Maven innards.)

The MicroBean Maven CDI project does just enough work to re-express certain Plexus components using CDI constructs so that you may simply inject the parts of maven-resolver that you need.

For example, to work with artifact repositories, you’re going to need a RepositorySystem and a RepositorySystemSession. With MicroBean Maven CDI, you simply do this:

@Inject
private RepositorySystem repositorySystem;

@Inject
private RepositorySystemSession repositorySystemSession;

…and the MavenExtension portable extension takes care of setting up the dozens of supporting objects for you behind the scenes.

MicroBean Maven CDI also natively understands your user-level ~/.m2/settings.xml file, and can use it so that you can inject the right remote repositories, even taking its local repository and mirrors settings into consideration:

@Inject
@Resolution // for dependency resolution, as opposed to, say, deployment
private List<RemoteRepository> remoteRepositories;

Usage

Here is some pseudocode showing how you might go about resolving the (arbitrarily chosen for this example) org.slf4j:slf4j-api:1.7.24 artifact from within your CDI bean:

import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.RepositorySystem;

import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;

import org.eclipse.aether.collection.CollectRequest;

import org.eclipse.aether.repository.RemoteRepository;

import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResolutionException;
import org.eclipse.aether.resolution.DependencyResult;

import org.eclipse.aether.util.artifact.JavaScopes;

import org.eclipse.aether.util.filter.DependencyFilterUtils;

@Inject
private RepositorySystem repositorySystem;

@Inject
private RepositorySystemSession session;

@Inject
@Resolution
private List<RemoteRepository> remoteRepositories;

public void resolve() throws DependencyResolutionException {
  final CollectRequest collectRequest = new CollectRequest();
  final Artifact artifact = new DefaultArtifact("org.slf4j", "slf4j-api", "jar", "1.7.24");
  collectRequest.setRoot(new Dependency(artifact, JavaScopes.COMPILE));
  collectRequest.setRepositories(remoteRepositories);

  final DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE));
  final DependencyResult dependencyResult = repositorySystem.resolveDependencies(session, dependencyRequest);
  final List<ArtifactResult> artifactResults = dependencyResult.getArtifactResults();
}