15

I'm looking for a Java API which can be used to retreive Maven artifacts from a remote repository. I've found Eclipse Ather so far but it looks over complicated for my needs so i'm seeking for something more simple.

What i need is:

  • I have to specify the location of the remote Maven repository
  • I like to fetch an artifact based on it's groupId + artifactId + version
  • The API have to provide the current remote version of the artifact (think about SNAPSHOT artifacts which are regularly built so they have a generated part in their versions)
  • Return the location of the artifact, a HTTP URL is preferred (i'll fetch it on my own with eg. Apache HTTP Client)
  • Optionally retreive the artifact's which are the dependants of the requested one.
vossad01
  • 11,552
  • 8
  • 56
  • 109
NagyI
  • 5,907
  • 8
  • 55
  • 83
  • It sounds like you try to reinvent the wheel with the Aether library. so i would take a deep look into the Aether lib and may be ask on their mailing list to see if a possibility exist to use a different artifact resolver (downloading later etc.). I doubt but just try it. – khmarbaise May 10 '12 at 16:03
  • 2
    Some ivy options listed here: http://stackoverflow.com/questions/3955209/using-ivy-dependencies-manager-programmatically/3963721#3963721 – Mark O'Connor May 10 '12 at 21:27

4 Answers4

10

jcabi-aether may help you (I'm a developer). It's a simple wrapper around Aether, that lets you find all transitive dependencies of a Maven artifact:

File repo = this.session.getLocalRepository().getBasedir();
Collection<Artifact> deps = new Aether(this.getProject(), repo).resolve(
  new DefaultArtifact("junit", "junit-dep", "", "jar", "4.10"),
  JavaScopes.RUNTIME
);

Thus, all you need to provide as an input is:

  • Local repo location, as a directory name
  • List of repote repositories (MavenProject#getRemoteRepositories())
  • Maven coordinates of the artifact
  • Maven scope to look for

Absolute paths of every dependency found can be obtained as Artifact#getPath()

yegor256
  • 102,010
  • 123
  • 446
  • 597
1
    public List<Artifact> findDependencies(Artifact artifact) throws DependencyCollectionException {

    CollectRequest collectRequest = new CollectRequest();
    collectRequest.setRoot( new Dependency(artifact, "" ) );
    collectRequest.addRepository(repository);

    final MavenServiceLocator locator = new MavenServiceLocator();
    locator.addService( RepositoryConnectorFactory.class, FileRepositoryConnectorFactory.class );
    locator.addService( RepositoryConnectorFactory.class, WagonRepositoryConnectorFactory.class );
    locator.setServices( WagonProvider.class, new WagonProvider() {
        public Wagon lookup(String roleHint) throws Exception {
            if (Arrays.asList("http", "https").contains(roleHint)) {
                return new LightweightHttpWagon();
            }
            return null;
        }

        public void release(Wagon wagon) {

        }
    });

    final RepositorySystem system = locator.getService(RepositorySystem.class);
    MavenRepositorySystemSession session = new MavenRepositorySystemSession();

    session.setLocalRepositoryManager( system.newLocalRepositoryManager(localRepository) );
    session.setTransferListener( new LoggingTransferListener() );
    session.setRepositoryListener( new LoggingRepositoryListener() );

    final List<Artifact> artifacts = new ArrayList<Artifact>();

    system.collectDependencies(session, collectRequest).getRoot().accept( new DependencyVisitor() {
        public boolean visitEnter(DependencyNode dependencyNode) {
            artifacts.add(dependencyNode.getDependency().getArtifact());
            return true;
        }

        public boolean visitLeave(DependencyNode dependencyNode) {
            return true;
        }
    });
    return artifacts;
}
alex.collins
  • 581
  • 4
  • 12
0

Aether jest actually pretty simple and elegant way of doing this. It's one of major enhancements in Maven 3 and many was looking for it. Look at this for some initial code to work with. I don't remember a method to get exact URL of the artifact, but other requirements are supported AFAIR.

Michał Kalinowski
  • 16,925
  • 5
  • 35
  • 48
  • One of the problems i don't like using Aether it's that i have to create a temporary repository just for fetching an artifact into it. I don't want Aether to download the file. I just want to know which is latest version of the artifact and where is it on the network. Imagine that i have an application distribution zip which doesn't have any dependant artifacts so it's just standing alone. I can fetch that easily by myself or even better unpack it on the fly while downloading. – NagyI May 10 '12 at 15:23
  • @Michal Kalinowski, the example you give shows how to use Aether in a maven plugin. Do you know of any docs that show how to use it in a regular (non-plugin) Java program? – user944849 May 10 '12 at 17:32
0

Have you tried using Apache Ivy? It supports fetching maven dependencies.

The documentation for this use case is a little bit sparse, but I found some information on programmatic use of Ivy here.

Sean Reilly
  • 21,526
  • 4
  • 48
  • 62
  • This is not absolutely programmatic. It needs predefined XML files which are defining the dependencies and other configurations. What if those are determined dynamically during execution (fetched from an external source)? I don't like to have temporary files all over the place. – NagyI May 10 '12 at 15:26
  • I think you might need those files to determine the remote repo location, but hopefully you wouldn't need to use the config files to retrieve specific dependencies. Gradle and SBT use ivy to fetch dependencies, and I think that they do it without xml config files. – Sean Reilly May 10 '12 at 16:04
  • I see. I'll dig deeper into Ivy then. Thanks! – NagyI May 10 '12 at 16:06