Wednesday, January 30, 2013

Analyzing JAR Dependencies

Today I've been analyzing the library dependencies of Vaadin libraries, mainly to find out which are used runtime and which during development, mainly for license purposes.

JarAnalyzer

The JarAnalyzer analyzes the dependencies between a collection of JAR libraries.

After extracting it to somewhere, it came with some BAT files. In Linux, I had to give the parameters on command-line:

$ java -cp ./lib/bcel-5.2.jar:./lib/jakarta-regexp-1.3.jar:./lib:./jaranalyzer-1.2.jar \
    com.kirkk.analyzer.textui.XMLUISummary \
    /ftp/tmp vaadin-7.0.0.rc2.xml

It also supported GraphViz DOT format, to generate a dependency graph:

$ java -cp ./lib/bcel-5.2.jar:./lib/jakarta-regexp-1.3.jar:./lib:./jaranalyzer-1.2.jar \
    com.kirkk.analyzer.textui.DOTSummary \
    /ftp/tmp vaadin-7.0.0.rc2.dot
$ dot -Tpng -o vaadin-7.0.0.rc2.png vaadin-7.0.0.rc2.dot

The problem was that some of the JARs included certain libraries inside them, so the dependencies were not precise enough.

JDepend

JDepend is another dependency analyzer, which analyzes the dependencies between the exact Java packages. It doesn't provide a graph as JarAnalyzer did, but has a rather textual GUI for browsing the package dependency trees.

Again, define the class path on command-line and give the JAR directory as the parameter:

$ java -cp lib/jdepend-2.9.1.jar jdepend.swingui.JDepend /ftp/tmp

The tool was quite useful for understanding some odd dependencies, but gave a bit too much information, as one library typically consists of quite a large number of Java packages.

Maven Dependencies

Listing the Maven dependencies was probably the best way to accomplish the task. Unfortunately, our dependecies were handled by Ivy, so I had to convert those to Maven dependencies. That was simple enough with the ivy:makepom task.

<target name="makepom">
    <ivy:makepom ivyfile="ivy.xml" pomfile="pom.xml">
   <mapping conf="default" scope="compile"/>
   <mapping conf="runtime" scope="runtime"/>
   </ivy:makepom>
</target>

Because of some odd inclusions, it generated duplicate dependencies. Those had to be removed manually.

To produce a textual dependency tree:

$ mvn dependency:tree
com.vaadin:vaadin-all:jar:7.0.0.rc2
+- com.vaadin:vaadin-shared:jar:7.0.0.rc2:compile
+- com.vaadin:vaadin-theme-compiler:jar:7.0.0.rc2:compile
|  +- org.apache.commons:commons-jexl:jar:2.1.1:compile
|  |  \- commons-logging:commons-logging:jar:1.1.1:compile
|  +- org.w3c.css:sac:jar:1.3:compile
|  +- net.sourceforge.cssparser:cssparser:jar:0.9.5:compile
|  \- commons-cli:commons-cli:jar:1.2:compile
+- com.vaadin:vaadin-server:jar:7.0.0.rc2:compile
|  \- org.jsoup:jsoup:jar:1.6.3:compile
+- com.vaadin:vaadin-client:jar:7.0.0.rc2:compile
|  +- javax.validation:validation-api:jar:1.0.0.GA:compile
|  \- javax.validation:validation-api:jar:sources:1.0.0.GA:compile
+- com.vaadin:vaadin-shared-deps:jar:1.0.2:compile
+- com.vaadin:vaadin-client-compiled:jar:7.0.0.rc2:compile
+- com.vaadin:vaadin-themes:jar:7.0.0.rc2:compile
\- com.vaadin:vaadin-client-compiler:jar:7.0.0.rc2:compile
   +- commons-collections:commons-collections:jar:3.1:compile
   +- ant:ant:jar:1.6.5:compile
   +- ant:ant-launcher:jar:1.6.5:compile
   +- org.mortbay.jetty:jetty:jar:6.1.11:compile
   |  \- org.mortbay.jetty:servlet-api-2.5:jar:6.1.11:compile
   +- org.mortbay.jetty:jetty-util:jar:6.1.11:compile
   +- org.jdesktop:swing-worker:jar:1.1:compile
   +- commons-codec:commons-codec:jar:1.3:compile
   +- commons-io:commons-io:jar:1.4:compile
   +- commons-lang:commons-lang:jar:2.6:compile
   \- org.apache.james:apache-mime4j:jar:0.6:compile

Or, as visualized with GraphViz. Using the outputType parameter required a newer version of the Maven Dependency plugin, so it required a full path to the most recent version:

$ mvn org.apache.maven.plugins:maven-dependency-plugin:2.6:tree \
      -DoutputFile=pom.dot -DoutputType=dot
$ dot -Tpng -o pom.png pom.dot

While this was in some way useful, it did not show dependencies included in the JARs, and didn't show all other dependencies either, so it was even less useful than JarAnalyzer display. Oh well.

3 comments:

Jason Rembert said...

you can use this site to download all this dependencies: http://jar-download.com/

Deba Sheesh said...

This is really a wonderful blog for some great information. I have been searching for a long time for this types of content. Keep up posting more and thanks for your great staff.
Battery Operated Ultrasonic Level Sensor

Deba Sheesh said...

Thanks, You wrote awesome, I have learn lots of things from your article. Its really helpful for any readers.
Battery Operated Flow Meter