On Fri, Jan 3, 2014 at 6:17 PM, Martin Gainty <mgai...@hotmail.com> wrote:
> MG>so I would say you are definitely on the right track > Thanks; I'm not sure I am. > MG>any reason for topological sorting of dependencies? > In my original post, I wrote: (As background: I am working with Liquibase (http://www.liquibase.org/). > Each of my .jar projects has a META-INF/liquibase/changelog.xml file in > it. Various of these .jar projects already depend on each other--for unit > and integration testing, I'd like to use this dependency order, harvest the > changelog.xml resources in each .jar file, and then combine them to create > only the database tables actually needed for the test. If a.jar has A's > tables, and b.jar has B's tables and b.jar depends on a.jar, then I'd like > to run a.jar!/META-INF/liquibase/changelog.xml first, then > b.jar!/META-INF/liquibase/changelog.xml next, and I'd like to not have to > specify this in any place in my pom.xmls, since the dependency order is > already captured there.) So the fact that I'm using ProjectSorter<http://maven.apache.org/ref/3.0.5/maven-core/apidocs/org/apache/maven/project/ProjectSorter.html>strikes me as wrong—worse than wrong: an awful hack, in fact—because I am basically using the reactor to sort MavenProjects that I've roped in from elsewhere. Yucko. Various people have noted tersely that the maven-dependency-plugin is what I want. Of course, its *goals* are completely useless for this task—but buried in an obscure StackOverflow comment tangentially related to the maven-dependency-plugin I found a reference to this class: http://maven.apache.org/shared/maven-dependency-tree/apidocs/index.html?org/apache/maven/shared/dependency/graph/DependencyGraphBuilder.html If I understand it right, then code like the following should do the trick (untested, but you get the general idea): public class Artifacts { private final DependencyGraphBuilder dependencyGraphBuilder; public Artifacts(final DependencyGraphBuilder dependencyGraphBuilder) { super(); this.dependencyGraphBuilder = dependencyGraphBuilder; } public Collection<? extends Artifact> getDependencyArtifactsInTopologicalOrder(final MavenProject project) throws DependencyGraphBuilderException { List<Artifact> returnValue = null; final DependencyNode projectNode = this.dependencyGraphBuilder.buildDependencyGraph(project, null /* no ArtifactFilter; prob. need one */); assert projectNode != null; final CollectingDependencyNodeVisitor visitor = new CollectingDependencyNodeVisitor(); projectNode.accept(visitor); final Collection<? extends DependencyNode> nodes = visitor.getNodes(); if (nodes != null && !nodes.isEmpty()) { returnValue = new ArrayList<Artifact>(); for (final DependencyNode node : nodes) { if (node != null) { final Artifact artifact = node.getArtifact(); if (artifact != null) { returnValue.add(artifact); } } } if (!returnValue.isEmpty()) { Collections.reverse(returnValue); } } return returnValue; } } I think that might be the right way to do it. It's unclear to me how Maven's internals themselves make use of this class, but it is probably used somewhere, and it clearly hides and mediates between the Sonatype Aether and Eclipse Aether kerfuffle that occurred between 3.0.5 and 3.1.x, so this also seems like something that isn't going to be deprecated any time soon. IWBNI there were a quick primer in the documentation somewhere about how Maven loads its own guts. I know that fundamentally Maven is just a bundle of components that get instantiated and wired together by Plexus but it sure is confusing to try to figure out how and where something is called—as a result when there are problems you have to go digging through, well, obscure StackOverflow questions. :-) Best, Laird -- http://about.me/lairdnelson