Skip to content

Instantly share code, notes, and snippets.

@vincent-zurczak
Last active September 8, 2018 01:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vincent-zurczak/282775f56d27e12a70d3 to your computer and use it in GitHub Desktop.
Save vincent-zurczak/282775f56d27e12a70d3 to your computer and use it in GitHub Desktop.
A Maven mojo that shows how to resolve dependencies locations, be it in remote or in the local repository, or even in the reactor.
package whatever;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.eclipse.aether.repository.RemoteRepository;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class CopyOfResolveMojoTest extends AbstractTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test( expected = MojoExecutionException.class )
public void testWithInvalidRoboconfDependencies() throws Exception {
// Prepare the project
final String projectName = "project--valid";
File baseDir = this.resources.getBasedir( projectName );
Assert.assertNotNull( baseDir );
Assert.assertTrue( baseDir.isDirectory());
AbstractMojo mojo = ...;
this.rule.setVariableValueToObject( mojo, "repoSession", newRepositorySession());
this.rule.setVariableValueToObject( mojo, "repositories", new ArrayList<RemoteRepository>( 0 ));
mojo.execute();
}
private RepositorySystemSession newRepositorySession() throws IOException {
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
RepositorySystem repositorySystem = locator.getService( RepositorySystem.class );
LocalRepository localRepo = new LocalRepository( this.folder.newFolder());
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
LocalRepositoryManager lrm = repositorySystem.newLocalRepositoryManager( session, localRepo );
session.setLocalRepositoryManager( lrm );
return session;
}
}
package whatever;
import java.io.File;
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
@Mojo( name="mojoName" )
public class ReactorDependenciesResolverMojo extends AbstractMojo {
@Parameter( defaultValue = "${project}", readonly = true )
private MavenProject project;
@Component
private RepositorySystem repoSystem;
@Parameter( defaultValue = "${repositorySystemSession}", readonly = true, required = true )
private RepositorySystemSession repoSession;
@Parameter( defaultValue = "${project.remoteProjectRepositories}", readonly = true, required = true )
private List<RemoteRepository> repositories;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
for( Artifact unresolvedArtifact : this.project.getDependencyArtifacts()) {
// Here, it becomes messy. We ask Maven to resolve the artifact's location.
// It may imply downloading it from a remote repository,
// searching the local repository or looking into the reactor's cache.
// To achieve this, we must use Aether
// (the dependency mechanism behind Maven).
String artifactId = unresolvedArtifact.getArtifactId();
org.eclipse.aether.artifact.Artifact aetherArtifact = new DefaultArtifact(
unresolvedArtifact.getGroupId(),
unresolvedArtifact.getArtifactId(),
unresolvedArtifact.getClassifier(),
unresolvedArtifact.getType(),
unresolvedArtifact.getVersion());
ArtifactRequest req = new ArtifactRequest().setRepositories( this.repositories ).setArtifact( aetherArtifact );
ArtifactResult resolutionResult;
try {
resolutionResult = this.repoSystem.resolveArtifact( this.repoSession, req );
} catch( ArtifactResolutionException e ) {
throw new MojoExecutionException( "Artifact " + artifactId + " could not be resolved.", e );
}
// The file should exists, but we never know.
File file = resolutionResult.getArtifact().getFile();
if( file == null || ! file.exists()) {
getLog().warn( "Artifact " + artifactId + " has no attached file. Its content will not be copied in the target model directory." );
continue;
}
// Do whatever you want with the file...
}
}
}
@vincent-zurczak
Copy link
Author

Notice this is intended for Maven 3.1 and higher versions.

@vincent-zurczak
Copy link
Author

The interest of unit tests to verify such a mojo is very limited.
People will generally opt to do integration tests with the Maven invoker plugin.

@chenhui0212
Copy link

Many thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment