Jump to: navigation, search

Aether/Setting Aether Up

< Aether
Revision as of 19:12, 22 April 2013 by Bentmann.sonatype.com (Talk | contribs) (Linked to actual demo source)

Aether's implementation consists of a bunch of components that need to be wired together to get a complete repository system. To satisfy different requirements and smoothly integrate into existing applications, Aether offers multiple ways to do so.


You can use a Plexus container (or any other dependency injection container that supports Plexus components like Sisu). For instance, assuming you add a dependency on org.sonatype.sisu:sisu-inject-plexus:2.3.0 to your POM, the following code fragment discovers the various Aether components from the thread context class loader and wires the system together:

import org.codehaus.plexus.DefaultPlexusContainer;
import org.eclipse.aether.RepositorySystem;
    private static RepositorySystem newRepositorySystem()
        throws Exception
        return new DefaultPlexusContainer().lookup( RepositorySystem.class );

We mostly mention this Plexus-based system setup here for completeness. The Plexus container is no longer maintained and users of it should start to migrate to alternatives like JSR-330.

JSR-330 / Guice / Sisu

Dependency injection is an established approach to component wiring and got standardized as part of JSR-330. Aether's components are equipped with javax.inject annotations to support usage in JSR-330-enabled applications.

Google Guice is a popular implemention of JSR-330. To ease usage of Aether in applications powered by Guice, Aether provides a ready-made Guice module that binds all the stock implementation classes. See our runnable demo snippets for a complete example using Guice.

For those seeking the simplicity of having components be discovered from the classpath as opposed to manually binding them, Sisu can help. Among others, it extends Guice with automatic/dynamic component discovery. Aether's JARs are equipped with Sisu index files to enable optimal performance during component discovery.

Service Locator

Sometimes, the overhead of using a full-blown dependency injection container is undesirable. 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. But 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.eclipse.aether.spi.locator.Service and org.eclipse.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 from the Apache Maven project provides a simple service locator for Aether whose usage looks like shown below:

import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.connector.wagon.WagonProvider;
import org.eclipse.aether.connector.wagon.WagonRepositoryConnectorFactory;
    private static RepositorySystem newRepositorySystem()
        DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
        locator.setServices( WagonProvider.class, new ManualWagonProvider() );
        locator.addService( RepositoryConnectorFactory.class, WagonRepositoryConnectorFactory.class );
        return locator.getService( RepositorySystem.class );

The DefaultServiceLocator created via MavenRepositorySystemUtils 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.