Dependency Management with JBoss Tattletale

By | December 27, 2014

JBoss Tattletale is not a new tool, in fact the latest version was released about three years ago and nothing has happened in the Git repository since. It still, to my knowledge, the best free tool to discover dependencies, relations and even collisions between dependencies.
In this article I will show how to use JBoss Tattletale from Maven and look at some of the reports produced by Tattletale.

Background

What first caused me to turn to Tattletale was when I wanted to use a newer version of the Apache HTTP Client in a program that used a library that has a dependency to an older version of said HTTP client. I experienced some strange problems and became quite puzzled before I realized that there were different classes that had the same name and resided in the same package on my class-path.

After having run Tattletale from the command-line a couple of times, my laziness struck me once again and decided to use the Tattletale Maven plug-in to be able to generate reports routinely when building my project.

Tattletale from Maven

I have chosen to create a Maven build profile for Tattletale report generation. There are a couple of reasons for this:

  • I want to have control over when to generate Tattletale reports.
    Report generation is time-consuming and I do not want to generate reports at every build.
  • Tattletale report generation require some preparations, as we will see, and I wanted to gather all the steps in one place.
    This enable me to either quickly copy the Maven build profile for Tattletale report generation to a new project or to include it in a parent pom-file, if one is available.

The Maven build profile for Tattletale report generation looks like this:

Report generation consists of these steps:

  • Copy JAR-files of all dependencies to temporary directory.
    While it is possible to specify multiple directories which Tattletale is to scan for JAR-files to analyze, I found it simpler to copy all the dependencies to one and the same directory.
  • Copy the JAR-file of the project to the temporary directory.
    This assumes that the project creates one single JAR-file. If your project creates multiple JAR-files or other types of files (WAR-file(s), for instance) or use a non-standard naming scheme for the files produced, you have to modify the contents of the <includes> element.
  • Generate Tattletale report(s).
    I have used a separate configuration file for Tattletale that enables more fine-grained configuration. We’ll examine this configuration file below.

Note the three properties (tattletale.tempdir, tattletale.reportdir and tattletale.configfile) in the profile – these allow you to customize the location of the temporary directory to which JAR-files are copied, the location of the directory to which generated reports are written and finally the location of the Tattletale configuration file.

A word of warning concerning the choice of directory which to write the report to:
Tattletale will delete the contents of this directory before generating reports, so do not chose a directory that contains files and/or folders that you do not want deleted.

If you like to clean up after Tattletale report generation and delete the temporary directory, add the following plug-in to the Maven profile listed above after the Tattletale plug-in:

Tattletale Configuration

As previously mentioned, I rely on a separate configuration file to configure Tattletale.
My configuration file looks like this:

Each configuration property is quite well commented in the file itself. However, there are a few things that I would like to emphasize:

  • I haven’t used the ‘profiles’ property except for setting the above values.
    You may want to consider creating additional profiles for, for instance, Java 7 and more recent versions of the Spring framework or any other frameworks that commonly are used in your organization.
  • I usually create all reports (using the ‘*’ wildcard, as above) but the reports that I have found most useful are:
    multiplejars – List classes that appear in more than one archive.
    blacklisted – List archives containing blacklisted classes and/or packages.
    dependson – For all archives, list the archives one archive directly depends on (no transitive dependencies).
    unusedjar – Tries to determine whether an archive is used or not. Note that an archive that is said to be unused may still be used through Java reflection or XML configuration.
  • If you want Tattletale to generate figures showing dependencies (the ‘graphviz’ report), you should be aware that this will make report generation very slow.
    Thus I almost exclusively set the ‘enableDot’ property to false.

Examples

In this section I will show some examples of the reports that I find most interesting. I have added the above Maven configuration to one of my projects and produced Tattletale reports.

multiplejars

As before, this report lists the classes that are found in more than one archive.

Excerpt of a multiplejars Tattletale report.

Excerpt of a multiplejars Tattletale report.

In the above example, we can see that, for instance, the javax.transaction.SystemException class appears in the following JAR-files:

  • activemq-all-5.9.0.jar
  • geronimo-jta_1.0.1B_spec-1.0.1.jar
  • geronimo-jta_1.1_spec-1.1.1.jar

In this example, I would take a look at which dependency, or which dependencies, that has a dependency to the geronimo-jta_1.0.1B_spec-1.0.1.jar and exclude it, if possible.
In this particular example, the geronimo-jta specification JAR-files include the version number in their Maven artifact ids, which cause Tattletale to consider these two archives as two different archives, not two different versions of the same archive. This is the reason for looking at the multiplejars report; while the Maven group id and artifact id of libraries may not always be consistent, the class names and packages in which the classes reside will despite this cause entries to appear in this report.

blacklisted

The blacklisted report can be used to discover use of deprecated code. In this example, I have the following configuration for blacklisted packages in the Tattletale configuration file:

The blacklisted report then looks like this:

A blacklisted Tattletale report.

A blacklisted Tattletale report.

On the left we first see in which archive the code that use blacklisted code is located, in this example the archive is message-cowboy-1.0.0-SNAPSHOT.jar. Below the name of the archive, we see which packages that contain code that use blacklisted code and on the right, in the Usage column, we see which entry in the blacklist that caused the entry to appear in the report.

dependson

The dependson report lists the direct dependencies (not including transitive dependencies) of archives.

Excerpt of a dependson Tattletale report.

Excerpt of a dependson Tattletale report.

In the above example we can see that the camel-core-2.12.1.jar depends on the activation-1.1-osgi.jar, the activemq-all-5.9.0.jar, the geronimo-stax-api_1.0_spec-1.0.1.jar, the jaxb-api-2.1.jar and the xpp3-1.1.3.4.O.jar.
In addition, there are a number of classes or interfaces that cannot be found in the available dependencies, for instance the javax.annotation.concurrent.GuardedBy annotation.

graphicaldependencies

The graphical dependencies report draws diagrams showing:

  • Dependencies of one archive.
  • Dependencies between packages in one archive.

The archive dependencies diagram is usually quite straightforward and shows the direct dependencies of an archive:

Archive dependencies diagram from the graphicaldependencies Tattletale report.

Archive dependencies diagram from the graphicaldependencies Tattletale report.

The package dependencies diagram shows dependencies between packages in one archive and direct dependencies to packages external to the archive:

Package dependencies diagram from the graphicaldependencies Tattletale report.

Package dependencies diagram from the graphicaldependencies Tattletale report.

Final Words

JBoss Tattletale definitely has a place in my toolbox. The major drawback, apart from a few minor bugs, is that the project seem more or less abandoned by JBoss and the author. The project is licensed under the GPL 2.1 license, so it is possible to fork it.
There is a JIRA at https://issues.jboss.org/projects/TTALE/summary and on Github, there are a few pull requests that fixes some bugs and implements new features, so there seem to be at least some interest in the project from the community.

Leave a Reply

Your email address will not be published. Required fields are marked *