|Aether has moved to Eclipse|
This wiki is obsolete and no longer maintained. Visit http://www.eclipse.org/aether/support/ instead.
Did you ever want to integrate Maven's dependency resolution mechanism into your application and ended up trying to embed Plexus and an entire Maven distribution? Did you ever want to use Maven's dependency resolution mechanism in a multi-threaded fashion and got burned by the stateful singletons in there? Did you ever want to have a little more control over how Maven calculates the resolved dependency graph, say use another strategy for conflict resolution?
Well, Aether is the answer. It's a standalone library to resolve, install and deploy artifacts the Maven way.
If you would like to take Aether for a test drive, these are the XML bits for your POM to get it onto your class path:
Let's have a closer look at these dependencies and what they are used for:
This JAR contains the application programming interfaces that clients of Aether use. The entry point to the system is org.sonatype.aether.RepositorySystem.
Here are various utility classes and ready-made components of the repository system collected.
This archive hosts many actual implementation classes of the repository system. Unless one intents to customize internals of the system or needs to manually wire it together, clients should not access any classes from this JAR directly.
The transport layer that handles the uploads/downloads of artifacts is realized by so called repository connectors. This particular connector adds support for transfers to and from file: URLs.
This connector enables access to http: and https: based repositories.
This connector is based on Maven Wagon and can employ any existing Wagon providers.
This dependency provides the pieces to employ Maven POMs as artifact descriptors and extract dependency information from them. Furthermore, it provides the handling of the other metadata files used in a Maven repository.
This dependency adds support for tranfers using the scp: and sftp: schemes. Its inclusion in the above POM snippet is merely a suggestion, use whatever Wagon providers fit your needs.
Note: Aether targets Java 1.5+ so be sure to set your compiler settings accordingly.
Aether's implementation consists of a bunch of components that need to be wired together to get a complete repository system. To do so, one can still use a Plexus container (or any other IoC container that supports Plexus components like Sisu). For instance, assuming you add a dependency on org.codehaus.plexus:plexus-container-default:1.5.5 to your POM the following code fragment discovers the various Aether components from the thread context class loader and wires the system together:
To get an instance of the repository system without an IoC container, the classes from the default implementation of Aether provide no-arg constructors and setters to manually wire the components together. Since this isn't really fun to code, the repository system additionally supports wiring via a lightweight service locator pattern. This service locator infrastructure consists of merely two small interfaces, namely org.sonatype.aether.spi.locator.Service and org.sonatype.aether.spi.locator.ServiceLocator. The components themselves implement the Service interface, and the client of the repository system provides to them an implementation of the ServiceLocator to query other components from. The module maven-aether-provider provides a simple service locator whose usage looks like shown below:
The DefaultServiceLocator already knows about all the components from aether-impl and maven-aether-provider, so the remaining missing bits that it needs to be told about are zero or more repository connectors. Once the locator's internal service registry is populated, the call to getService() will create the repository system and recursively initialize its sub components.
For the future, it's intended to provide an additional service locator implementation that is capable of discovering components automatically from the class path.
Aether and its components are designed to be stateless and as such all configuration has be passed into the methods. When one makes multiple requests to resolve dependencies, a fair amount of settings usually remains the same across these method calls, like the proxy settings or the path to the local repository. Those settings that tend to be the same for an entire usage session of the repository system are represented by an instance of org.sonatype.aether.RepositorySystemSession. Using classes from maven-aether-provider, creating such a session that mimics Maven's setup can be done like this:
As you see, the only setting that must be specified is the local repository, other settings are initialized with default values. Please have a look at the API docs for MavenRepositorySystemSession to learn about all the other things you can configure for a session.
If you seek a close cooperation with stock Maven and want to read configuration from the user's settings.xml, you should have a look at the library org.apache.maven:maven-settings-builder which provides the necessary bits.
Extending the previous code snippets, the snippet below demonstrates how to actually resolve the transitive dependencies of org.apache.maven:maven-profile:2.2.1 in this example and to dump the result as a class path to the console:
So once you have initialized the repository system and created a session, the general pattern is to create some request object, call its setters to configure the request, do the operation and evaluate the result object. The module aether-demo from the Aether source repository provides a more extensive demonstration of Aether and its use, so feel free to play with that.
To learn about how you can control the calculation of transitive dependencies, please see the article about the Introduction.
Aether is not just another way to do Maven-like dependency resolution, it is the library that Maven 3 actually integrates for all the dependency related work. So if you are curious how to use Aether from your Maven plugin, check out Using Aether in Maven Plugins.