Quantcast

Sort dependencies topologically

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Sort dependencies topologically

Jérémy
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sort dependencies topologically

ljnelson
On Mon, Nov 7, 2011 at 12:29 PM, Jérémy <[hidden email]> 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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sort dependencies topologically

Jérémy
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 <[hidden email]> wrote:

> On Mon, Nov 7, 2011 at 12:29 PM, Jérémy <[hidden email]> 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
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sort dependencies topologically

ljnelson
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 <[hidden email]> 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 <[hidden email]> wrote:
>
> > On Mon, Nov 7, 2011 at 12:29 PM, Jérémy <[hidden email]> 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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sort dependencies topologically

Ansgar Konermann
In reply to this post by Jérémy
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: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sort dependencies topologically

Ansgar Konermann
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: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sort dependencies topologically

Jérémy
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 <
[hidden email]> 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: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sort dependencies topologically

Jérémy
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 <[hidden email]> 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 <
> [hidden email]> 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: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
>>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sort dependencies topologically

Barrie Treloar
On Fri, Nov 25, 2011 at 11:41 PM, Jérémy <[hidden email]> 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: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sort dependencies topologically

Jérémy
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 <[hidden email]> wrote:

> On Fri, Nov 25, 2011 at 11:41 PM, Jérémy <[hidden email]> 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: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Loading...