You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by Jérémy <me...@gmail.com> on 2011/11/07 18:29:27 UTC

Sort dependencies topologically

Hi,

I'm trying to sort the dependencies expressed in the pom.xml (including the
transitive ones) in a topological way. I'm using the maven-* API
3.0-alpha-2 and it is in the context of a plugin. I tried to use Maven's
embedded API to do so, but I get a NPE when I
call getTopologicallySortedProjects().
Here's a snippet of my Mojo:

MavenExecutionResult dm = new DefaultMavenExecutionResult();
dm = dm.setProject(getMavenProject()); //Maven project provided by plexus
List<MavenProject> list = dm.getTopologicallySortedProjects();

Anyone has any experience with that?

Cheers,
Jérémy

Re: Sort dependencies topologically

Posted by Laird Nelson <lj...@gmail.com>.
Ah, yes, in my case I needed to do it in a plugin, so I marked my plugin as
requiring dependency resolution in the test scope and could therefore rest
assured that all dependencies were resolved.

I'm afraid you're on your own in undocumented Maven-land!  :-)

Best,
Laird

On Tue, Nov 8, 2011 at 4:42 AM, Jérémy <me...@gmail.com> wrote:

> Hi Laird,
>
> Thanks for your answer! It's funny because I already tried your piece of
> code, but couldn't get it running. That's the reason why I went on another
> direction :-)
>
> Can you please provide a complete example? Because I have problems when it
> comes to retrieve MavenProject objects with the buildFromRepository method.
> It throws some exceptions. I suspect that my artifacts are not always
> resolved when I call this method.
>
> Thank you so much!
> Jérémy
>
> On Mon, Nov 7, 2011 at 6:44 PM, Laird Nelson <lj...@gmail.com> wrote:
>
> > On Mon, Nov 7, 2011 at 12:29 PM, Jérémy <me...@gmail.com> wrote:
> >
> > > I'm trying to sort the dependencies expressed in the pom.xml (including
> > the
> > > transitive ones) in a topological way.
> > >
> >
> > Hello; I faced the same problem and found a solution.  Given that most of
> > the classes involved were undocumented, it remains hard to know if this
> is
> > the proper way to do it, but it works for me.
> >
> >
> >
> http://maven.40175.n5.nabble.com/Topologically-sorting-dependencies-td3384898.html
> >
> > Best,
> > Laird
> >
> > --
> > http://about.me/lairdnelson
> >
>



-- 
http://about.me/lairdnelson

Re: Sort dependencies topologically

Posted by Jérémy <me...@gmail.com>.
Hi Laird,

Thanks for your answer! It's funny because I already tried your piece of
code, but couldn't get it running. That's the reason why I went on another
direction :-)

Can you please provide a complete example? Because I have problems when it
comes to retrieve MavenProject objects with the buildFromRepository method.
It throws some exceptions. I suspect that my artifacts are not always
resolved when I call this method.

Thank you so much!
Jérémy

On Mon, Nov 7, 2011 at 6:44 PM, Laird Nelson <lj...@gmail.com> wrote:

> On Mon, Nov 7, 2011 at 12:29 PM, Jérémy <me...@gmail.com> wrote:
>
> > I'm trying to sort the dependencies expressed in the pom.xml (including
> the
> > transitive ones) in a topological way.
> >
>
> Hello; I faced the same problem and found a solution.  Given that most of
> the classes involved were undocumented, it remains hard to know if this is
> the proper way to do it, but it works for me.
>
>
> http://maven.40175.n5.nabble.com/Topologically-sorting-dependencies-td3384898.html
>
> Best,
> Laird
>
> --
> http://about.me/lairdnelson
>

Re: Sort dependencies topologically

Posted by Laird Nelson <lj...@gmail.com>.
On Mon, Nov 7, 2011 at 12:29 PM, Jérémy <me...@gmail.com> wrote:

> I'm trying to sort the dependencies expressed in the pom.xml (including the
> transitive ones) in a topological way.
>

Hello; I faced the same problem and found a solution.  Given that most of
the classes involved were undocumented, it remains hard to know if this is
the proper way to do it, but it works for me.

http://maven.40175.n5.nabble.com/Topologically-sorting-dependencies-td3384898.html

Best,
Laird

-- 
http://about.me/lairdnelson

Re: Sort dependencies topologically

Posted by Jérémy <me...@gmail.com>.
Here it is, it sorts only the artifactId, I retrieved the versions through
other means.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.sonatype.aether.RepositorySystem;
import org.sonatype.aether.RepositorySystemSession;
import org.sonatype.aether.collection.CollectRequest;
import org.sonatype.aether.collection.CollectResult;
import org.sonatype.aether.collection.DependencyCollectionException;
import org.sonatype.aether.graph.Dependency;
import org.sonatype.aether.graph.DependencyNode;
import org.sonatype.aether.repository.RemoteRepository;
import org.sonatype.aether.util.DefaultRepositorySystemSession;
import org.sonatype.aether.util.artifact.DefaultArtifact;
import org.sonatype.aether.util.graph.PostorderNodeListGenerator;
import
org.sonatype.aether.util.graph.transformer.NoopDependencyGraphTransformer;

/**
 *
 * @goal z
 *
 */
public class MyMojo extends AbstractMojo {
/**
 * The entry point to Aether, i.e. the component doing all the work.
 *
 * @component
 */
private RepositorySystem repoSystem;

/**
 * The current repository/network configuration of Maven.
 *
 * @parameter default-value="${repositorySystemSession}"
 * @readonly
 */
private RepositorySystemSession repoSession;

/**
 * The project's remote repositories to use for the resolution.
 *
 * @parameter default-value="${project.remoteProjectRepositories}"
 * @readonly
 */
private List<RemoteRepository> remoteRepos;

/**
 * @parameter default-value="${project}"
 * @readonly
 */
private MavenProject project;

public void execute() throws MojoFailureException, MojoExecutionException {
// Create the root node
Dependency dependency = new Dependency(new
DefaultArtifact(project.getArtifact().getId()), "compile");

// Collect the whole expanded dependency tree, where nodes can be
// duplicated and no conflicts have been resolved
CollectRequest collectRequest = new CollectRequest();
collectRequest.setRoot(dependency);
collectRequest.setRepositories(remoteRepos);
CollectResult collectResult = null;
try {
DefaultRepositorySystemSession myRepoSession = new
DefaultRepositorySystemSession(repoSession);
NoopDependencyGraphTransformer myVisitor = new
NoopDependencyGraphTransformer();
myRepoSession = myRepoSession.setDependencyGraphTransformer(myVisitor);
collectResult = repoSystem.collectDependencies(myRepoSession,
collectRequest);
} catch (DependencyCollectionException e) {
e.printStackTrace();
}

// Sorting the whole dependency tree using Postorder from Aether
PostorderNodeListGenerator nlg = new PostorderNodeListGenerator();
DependencyNode node = collectResult.getRoot();
node.accept(nlg);

// Excluding the duplicated nodes, we start from the top of the list and
// exclude any node which has already been seen
List<DependencyNode> nodesList = nlg.getNodes();
List<DependencyNode> seenList = new ArrayList<DependencyNode>();
for (Iterator<DependencyNode> it = nodesList.iterator(); it.hasNext();) {
DependencyNode dep = it.next();
if (contains(seenList, dep)) {
it.remove();
} else {
seenList.add(dep);
}
}

// Topological sort is a revert postorder sort
Collections.reverse(nodesList);

// Finally, only the artifactIds are extracted. The versions don't match
// Maven's resolver.
// We can resolve versions by using Aether's
// NearestVersionConflictResolver graph transformer, but in our case the
// artifactIds were sufficient.
List<String> sortedDependencies = new LinkedList<String>();
for (DependencyNode dependencyNode : nodesList) {
sortedDependencies.add(dependencyNode.getDependency().getArtifact().getArtifactId());
}

System.out.println("Sorted dependencies:");
for (String artifactId : sortedDependencies) {
System.out.println(artifactId);
}

}

private boolean contains(List<DependencyNode> seenList, DependencyNode dep)
{
for (DependencyNode node : seenList) {
if (dep.getDependency().getArtifact().getArtifactId()
.equals(node.getDependency().getArtifact().getArtifactId())) {
return true;
}
}
return false;
}
}

On Sat, Nov 26, 2011 at 8:56 PM, Barrie Treloar <ba...@gmail.com> wrote:

> On Fri, Nov 25, 2011 at 11:41 PM, Jérémy <me...@gmail.com> wrote:
> > Hi guys,
> >
> > I've finally succeeded!
> >
> > The trick was to play with the DependencyGraphTransformers in order to
> get
> > a non-reducted dependency tree. Then I used Aether's
> PostorderNodeListGenerator
> > to sort the nodes, and finally I removed the duplicated nodes.
>
> Any code snippets?
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
>

Re: Sort dependencies topologically

Posted by Barrie Treloar <ba...@gmail.com>.
On Fri, Nov 25, 2011 at 11:41 PM, Jérémy <me...@gmail.com> wrote:
> Hi guys,
>
> I've finally succeeded!
>
> The trick was to play with the DependencyGraphTransformers in order to get
> a non-reducted dependency tree. Then I used Aether's PostorderNodeListGenerator
> to sort the nodes, and finally I removed the duplicated nodes.

Any code snippets?

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Sort dependencies topologically

Posted by Jérémy <me...@gmail.com>.
Hi guys,

I've finally succeeded!

The trick was to play with the DependencyGraphTransformers in order to get
a non-reducted dependency tree. Then I used Aether's PostorderNodeListGenerator
to sort the nodes, and finally I removed the duplicated nodes.

Thanks a lot,
Jérémy

On Wed, Nov 9, 2011 at 2:32 PM, Jérémy <me...@gmail.com> wrote:

> Thank you guys!
>
> I'll give a try to the Aether implementation :-)
>
> Regards,
> Jérémy
>
>
> On Tue, Nov 8, 2011 at 9:41 PM, Ansgar Konermann <
> ansgar.konermann@googlemail.com> wrote:
>
>> Am 08.11.2011 21:36, schrieb Ansgar Konermann:
>> >
>> > Example code can be found
>> > [...]
>> Some more example code here:
>>
>> https://docs.sonatype.org/display/AETHER/Home
>>
>>
>> Ansgar
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
>> For additional commands, e-mail: users-help@maven.apache.org
>>
>>
>

Re: Sort dependencies topologically

Posted by Jérémy <me...@gmail.com>.
Thank you guys!

I'll give a try to the Aether implementation :-)

Regards,
Jérémy

On Tue, Nov 8, 2011 at 9:41 PM, Ansgar Konermann <
ansgar.konermann@googlemail.com> wrote:

> Am 08.11.2011 21:36, schrieb Ansgar Konermann:
> >
> > Example code can be found
> > [...]
> Some more example code here:
>
> https://docs.sonatype.org/display/AETHER/Home
>
>
> Ansgar
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
>

Re: Sort dependencies topologically

Posted by Ansgar Konermann <an...@googlemail.com>.
Am 08.11.2011 21:36, schrieb Ansgar Konermann:
>
> Example code can be found
> [...]
Some more example code here:

https://docs.sonatype.org/display/AETHER/Home


Ansgar

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Sort dependencies topologically

Posted by Ansgar Konermann <an...@googlemail.com>.
Am 07.11.2011 18:29, schrieb Jérémy:
> Hi,
>
> I'm trying to sort the dependencies expressed in the pom.xml (including the
> transitive ones) in a topological way.

Sonatype / Eclipse Aether can help with this. I use it myself for
exactly the purpose you describe here to build a post-order depth first
visit sequence of the (transitive) dependency tree. This is then used to
load the dependencies in this order to match requirements of the
underlying technology (JBoss Drools). If you use Aether, you get this
kind of sorting for free (pre-order, post-order depth-first are
supported out of the box). Look out for PostorderNodeListGenerator,
PreorderNodeListGenerator in package org.sonatype.aether.util.graph.

Aether is also used by Maven internally to do dependency resolution and
stuff. It's currently in incubation at eclipse.org and licensed under EPL.

Source code is available on github [1]

Example code can be found
* in maven-drools-plugin [2]
* blog post about using aether in plugins [3]

Best regards

Ansgar

[1] https://github.com/sonatype/sonatype-aether
[2]
https://github.com/maven-drools/plugin.maven-drools-plugin/tree/master/mojos
[3]
http://www.sonatype.com/people/2011/01/how-to-use-aether-in-maven-plugins/
>  I'm using the maven-* API
> 3.0-alpha-2 and it is in the context of a plugin. I tried to use Maven's
> embedded API to do so, but I get a NPE when I
> call getTopologicallySortedProjects().
> Here's a snippet of my Mojo:
>
> MavenExecutionResult dm = new DefaultMavenExecutionResult();
> dm = dm.setProject(getMavenProject()); //Maven project provided by plexus
> List<MavenProject> list = dm.getTopologicallySortedProjects();
>
> Anyone has any experience with that?
>
> Cheers,
> Jérémy
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org