Maven dependency:tree vs. dependency:list

I have used the Maven dependency plugin‘s dependency:tree goal before to show my project’s dependencies, including transitive dependencies.  Sometimes, though, I would rather show the dependencies in a flat format such as what Maven’s dependency:list goal provides, but I wasn’t sure if it was all the same information or not… thus this analysis.

Comparing The Two

Maven dependency:tree

Here’s sample output from a run of Maven the dependency:tree goal:

[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'dependency'.
[INFO] org.apache.maven.plugins: checking for updates from central
[INFO] org.codehaus.mojo: checking for updates from central
[INFO] ------------------------------------------------------------------------
[INFO] Building JNDI via Bitronix Transaction Manager
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree]
[INFO] com.example.research.jndi.jndi-bitronix:jndi-bitronix:jar:1-SNAPSHOT
[INFO] +- log4j:log4j:jar:1.2.15:compile
[INFO] +- org.apache.activemq:activemq-core:jar:5.1.0:compile
[INFO] |  +- commons-logging:commons-logging-api:jar:1.1:compile
[INFO] |  +- org.apache.camel:camel-core:jar:1.3.0:compile
[INFO] |  |  +- javax.xml.bind:jaxb-api:jar:2.1:compile
[INFO] |  |  |  +- javax.xml.stream:stax-api:jar:1.0-2:compile
[INFO] |  |  |  \- javax.activation:activation:jar:1.1:compile
[INFO] |  |  \- com.sun.xml.bind:jaxb-impl:jar:2.1.3:compile
[INFO] |  +- org.apache.geronimo.specs:geronimo-jms_1.1_spec:jar:1.1.1:compile
[INFO] |  \- org.apache.geronimo.specs:geronimo-j2ee-management_1.0_spec:jar:1.0:compile
[INFO] +- org.springframework:spring-tx:jar:2.5.5:compile
[INFO] |  +- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] |  +- org.springframework:spring-beans:jar:2.5.5:compile
[INFO] |  +- org.springframework:spring-context:jar:2.5.5:compile
[INFO] |  \- org.springframework:spring-core:jar:2.5.5:compile
[INFO] +- org.springframework:spring-jms:jar:2.5.5:compile
[INFO] |  +- commons-pool:commons-pool:jar:1.3:compile
[INFO] |  \- org.springframework:spring-context-support:jar:2.5.5:compile
[INFO] +- org.springframework:spring-aop:jar:2.5.5:compile
[INFO] |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] +- org.springframework:spring-aspects:jar:2.5.5:compile
[INFO] |  +- org.aspectj:aspectjrt:jar:1.6.0:compile
[INFO] |  \- org.aspectj:aspectjweaver:jar:1.6.0:compile
[INFO] +- org.hibernate:hibernate:jar:3.2.6.ga:compile
[INFO] |  +- net.sf.ehcache:ehcache:jar:1.2.3:compile
[INFO] |  +- asm:asm-attrs:jar:1.5.3:compile
[INFO] |  +- dom4j:dom4j:jar:1.6.1:compile
[INFO] |  +- antlr:antlr:jar:2.7.6:compile
[INFO] |  +- asm:asm:jar:1.5.3:compile
[INFO] |  \- commons-collections:commons-collections:jar:2.1.1:compile
[INFO] +- cglib:cglib-nodep:jar:2.1_3:compile
[INFO] +- javax.transaction:jta:jar:1.0.1B:compile
[INFO] +- org.springframework:spring-orm:jar:2.5.5:compile
[INFO] +- org.springframework:spring-jdbc:jar:2.5.5:compile
[INFO] +- org.codehaus.btm:btm:jar:1.3:compile
[INFO] |  +- org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0.1:compile
[INFO] |  \- org.slf4j:slf4j-api:jar:1.5.2:compile
[INFO] +- junit:junit:jar:4.4:test
[INFO] +- commons-dbcp:commons-dbcp:jar:1.2.2:test
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.4.3:runtime
[INFO] \- com.oracle:ojdbc5:jar:11.1.0.6.0:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13 seconds
[INFO] Finished at: Wed Aug 27 12:05:14 EDT 2008
[INFO] Final Memory: 12M/23M
[INFO] ------------------------------------------------------------------------

Forty-one dependencies.

Maven dependency:list

There is another Maven dependency plugin goal: dependency:list.  It displays the same project’s dependencies in a flat, alphabetically-sorted list:

[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'dependency'.
[INFO] ------------------------------------------------------------------------
[INFO] Building JNDI via Bitronix Transaction Manager
[INFO]    task-segment: [dependency:list]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:list]
[INFO]
[INFO] The following files have been resolved:
[INFO]    antlr:antlr:jar:2.7.6:compile
[INFO]    aopalliance:aopalliance:jar:1.0:compile
[INFO]    asm:asm:jar:1.5.3:compile
[INFO]    asm:asm-attrs:jar:1.5.3:compile
[INFO]    cglib:cglib-nodep:jar:2.1_3:compile
[INFO]    com.oracle:ojdbc5:jar:11.1.0.6.0:compile
[INFO]    com.sun.xml.bind:jaxb-impl:jar:2.1.3:compile
[INFO]    commons-collections:commons-collections:jar:2.1.1:compile
[INFO]    commons-dbcp:commons-dbcp:jar:1.2.2:test
[INFO]    commons-logging:commons-logging:jar:1.1.1:compile
[INFO]    commons-logging:commons-logging-api:jar:1.1:compile
[INFO]    commons-pool:commons-pool:jar:1.3:compile
[INFO]    dom4j:dom4j:jar:1.6.1:compile
[INFO]    javax.activation:activation:jar:1.1:compile
[INFO]    javax.transaction:jta:jar:1.0.1B:compile
[INFO]    javax.xml.bind:jaxb-api:jar:2.1:compile
[INFO]    javax.xml.stream:stax-api:jar:1.0-2:compile
[INFO]    junit:junit:jar:4.4:test
[INFO]    log4j:log4j:jar:1.2.15:compile
[INFO]    net.sf.ehcache:ehcache:jar:1.2.3:compile
[INFO]    org.apache.activemq:activemq-core:jar:5.1.0:compile
[INFO]    org.apache.camel:camel-core:jar:1.3.0:compile
[INFO]    org.apache.geronimo.specs:geronimo-j2ee-management_1.0_spec:jar:1.0:compile
[INFO]    org.apache.geronimo.specs:geronimo-jms_1.1_spec:jar:1.1.1:compile
[INFO]    org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0.1:compile
[INFO]    org.aspectj:aspectjrt:jar:1.6.0:compile
[INFO]    org.aspectj:aspectjweaver:jar:1.6.0:compile
[INFO]    org.codehaus.btm:btm:jar:1.3:compile
[INFO]    org.hibernate:hibernate:jar:3.2.6.ga:compile
[INFO]    org.slf4j:slf4j-api:jar:1.5.2:compile
[INFO]    org.slf4j:slf4j-log4j12:jar:1.4.3:runtime
[INFO]    org.springframework:spring-aop:jar:2.5.5:compile
[INFO]    org.springframework:spring-aspects:jar:2.5.5:compile
[INFO]    org.springframework:spring-beans:jar:2.5.5:compile
[INFO]    org.springframework:spring-context:jar:2.5.5:compile
[INFO]    org.springframework:spring-context-support:jar:2.5.5:compile
[INFO]    org.springframework:spring-core:jar:2.5.5:compile
[INFO]    org.springframework:spring-jdbc:jar:2.5.5:compile
[INFO]    org.springframework:spring-jms:jar:2.5.5:compile
[INFO]    org.springframework:spring-orm:jar:2.5.5:compile
[INFO]    org.springframework:spring-tx:jar:2.5.5:compile
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7 seconds
[INFO] Finished at: Wed Aug 27 12:09:48 EDT 2008
[INFO] Final Memory: 11M/23M
[INFO] ------------------------------------------------------------------------

Does one of these views show dependencies the other does not?  Let’s find out.

Comparing The Two

If we strip off [INFO] and the line drawing characters from the beginning of the line and then sort the dependency tree, we get a list identical to the list produced by the dependency:list command: The same 41 dependencies are listed, just in different formats.

Because 41 dependencies is a lot to eyeball and so I wouldn’t miss any subtle differences, I saved the relevant lines of the dependency:tree output as dep-tree.txt, and the relevant lines of the dependency:list output as dep-list.txt, and used some Cygwin commands:

< dep-tree.txt cut --delimiter="&#93;" --fields=2- | sed "s/^&#91; |+\\-&#93;*//" | sort > dep-tree.srt
< dep-list.txt cut --delimiter="&#93;" --fields=2- | sed "s/^&#91; |+\\-&#93;*//" | sort > dep-list.srt
diff --report-identical-files dep-tree.srt dep-list.srt

This yielded the following output:

Files dep-tree.srt and dep-list.srt are identical

Conclusion: dependency:tree and dependency:list seem to show the same information — it’s just a matter of how you want to view it.

Maven dependency:tree In Eclipse

You can set up these plugins as external tools in Eclipse.  Here’s an example for dependency:tree :

(This assumes you have an M2_HOME environment variable pointing to your Maven 2 installation directory.  An alternative would be to put the full path in there directly.)

Future Directions

Are We Pointing to the Same-ish Thing Twice?

Something I lack at the moment is a quick way of finding out if my project’s dependencies include the same artifact twice — for instance, two different versions of the same artifact.  (I think Maven already has rules to deal with this type of situation, but because the app server can be finicky about this type of thing, I’d still like an easy way to find out if I have two transitive dependencies on the same artifactId.)

[Update: see Listing Artifact Conflicts with Maven]

Do our Declarations Match our Usage?

It looks like the dependency:analyze goal could be helpful to us too:

Analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared.

Its sister, the dependency:analyze-only goal, can be used as part of the build process, and can optionally fail the build if the dependencies aren’t set up right.

3 thoughts on “Maven dependency:tree vs. dependency:list

  1. Thanks, Guo! You just saved my day. I was wondering why I got different dependencies with Maven 2 vs Maven 3 and tree vs list. That mailing list notice was easy to miss.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.