Tuesday, April 28, 2009

Optimizing with the Maven Dependency Plugin

$ mvn dependency:analyze

[WARNING] Used undeclared dependencies found:
[WARNING] org.sonatype.mavenbook.ch08:simple-model:jar:1.0:compile
[WARNING] Unused declared dependencies found:
[WARNING] org.apache.velocity:velocity:jar:1.5:compile
[WARNING] javax.servlet:jstl:jar:1.1.2:compile
[WARNING] taglibs:standard:jar:1.1.2:compile
[WARNING] junit:junit:jar:3.8.1:test

This goal analyzes the project to see whether there are any indirect dependencies, or dependencies that are being referenced but are not directly declared. In the simple-model project, the Dependency plugin indicates a “used undeclared dependency” on javax.persistence:persistence-api. To investigate further, go to the simple-model directory and run the dependency:tree goal, which will list all of the project’s direct and transitive dependencies:

$ mvn dependency:tree
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'dependency'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Chapter 8 Simple Object Model
[INFO] task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree]
[INFO] org.sonatype.mavenbook.ch08:simple-model:jar:1.0
[INFO] +- org.hibernate:hibernate-annotations:jar:3.3.0.ga:compile
[INFO] | \- javax.persistence:persistence-api:jar:1.0:compile
[INFO] +- org.hibernate:hibernate:jar:3.2.5.ga:compile
[INFO] | +- net.sf.ehcache:ehcache:jar:1.2.3:compile
[INFO] | +- commons-logging:commons-logging:jar:1.0.4: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] | +- cglib:cglib:jar:2.1_3:compile
[INFO] | +- asm:asm:jar:1.5.3:compile
[INFO] | \- commons-collections:commons-collections:jar:2.1.1:compile
[INFO] \- junit:junit:jar:3.8.1:test

From this output, we can see that the persistence-api dependency is coming from hibernate. A cursory scan of the source in this module will reveal many javax.persistence import statements confirming that we are, indeed, directly referencing this dependency. The simple fix is to add a direct reference to the dependency. A good rule of thumb in Maven is to always declare explicit dependencies for classes referenced in your code.

In contrast, the list of unused, declared dependencies is a little trickier to validate, and less useful than the “used, undeclared dependencies.” For one, some dependencies are used only at runtime or for tests, and they won’t be found in the bytecode. These are pretty obvious when you see them in the output; for example, JUnit appears in this list, but this is expected because it is used only for unit tests. You’ll also notice that the Velocity and Servlet API dependencies are listed in this list for the simple-web module. This is also expected because, although the project doesn’t have any direct references to the classes of these artifacts, they are still essential during runtime. Be careful when removing any unused, declared dependencies.

No comments:

Post a Comment