26.11. DependencyFinder

26.11.1. Overview

The DependencyFinder Sensor is an Ant task that sends information about dependencies, or couplings, produced by the Dependency Finder tool to the Hackystat server. The DependencyFinder sensor represents this metric data using the Dependency sensor data type, documented in Section 25.9, “Dependency”

Dependency Finder is a tool for analyzing compiled Java code to produce a variety of dependency graphs. Table 26.5, “DependencyFinder Metrics” lists the specific dependency metrics gathered by the DependencyFinder sensor.

Table 26.5. DependencyFinder Metrics

MetricDescription
granularityTwo granularities of dependencies are collected by this sensor: package-level dependencies, and class-level dependencies.
runTimeThe UTC time when the DependencyFinder tool was invoked to generate information regarding the system.
pathThe fully qualified file path of the resource (package or class) to which the dependency data refers.
inboundA list of the objects that depend upon the object specified by the "name" field.
outboundA list of the objects that the object specified by the "name" field depends upon.

26.11.2. Installation

26.11.2.1. Prerequisites

The DependencyFinder sensor requires Java 1.5.0 or later, Ant 1.6.5 or later, and Dependency Finder 1.1.0 beta2 or later.

26.11.2.2. Install DependencyFinder

Download Dependency Finder 1.1.0 beta2 or later from its home page and install in your local environment. Section 4.10, “Measurement: Structural coupling with DependencyFinder” provides a recommended approach to DependencyFinder installation for use with Hackystat.

26.11.2.3. Download HackyInstaller and set your Hackystat Host and User Key

Follow the instructions in Chapter 2, Client-side configuration: Tool sensor installation to set your Hackystat host and user key.

26.11.2.4. Configure and install the DependencyFinder sensor

In the HackyInstaller main window, select the DependencyFinder sensor and press "Configure Selected Sensor". Figure 26.16, “ DependencyFinder sensor installer configuration window ” shows what the configuration window should look like after the path to Ant is set, the sensor is enabled, and the "Install" button has been pressed to install the sensor.

Figure 26.16.  DependencyFinder sensor installer configuration window


DependencyFinder sensor installer configuration window

This sensor supports the following properties and paths:

  • Enable DependencyFinder Sensor: This property controls whether the sensor is active or not. If not checked, the sensor will not collect or send data even if installed.

  • Ant home directory: This path specifies the top-level directory for Ant. The DependencyFinder sensor requires the placement of a sensor executable into Ant's lib/ directory.

26.11.2.5. Define Ant targets to run the DependencyFinder tool and the DependencyFinder sensor

Example 26.28, “Example dependencyfinder.tool, dependencyfinder.report, and dependencyfinder.sensor targets” illustrates one possible definition of these targets.

Example 26.28. Example dependencyfinder.tool, dependencyfinder.report, and dependencyfinder.sensor targets

  <target name="dependencyfinder" depends="dependencyfinder.tool, dependencyfinder.report, dependencyfinder.sensor" 
   description="Runs DependencyFinder tool, report, and sensor."/>

  <target name="dependencyfinder.tool" depends="compile" description="Computes dependency metrics on the source code.">
    <!-- Verify that DependencyFinder is installed. -->
    <available file="${env.DEPENDENCYFINDER_HOME}/lib/DependencyFinder.jar" property="dependencyfinder.available"/>
    <fail unless="dependencyfinder.available" message="Error: DEPENDENCYFINDER_HOME not set or dependencyfinder.jar not found."/>
    <taskdef name="dependencyextractor" classname="com.jeantessier.dependencyfinder.ant.DependencyExtractor" classpathref="dependencyfinder.path"/>    
    <!-- Run the DependencyFinder tool. -->
    <mkdir dir="${dependencyfinder.dir}"/>
    <dependencyextractor destfile="${dependencyfinder.dir}/all.xml" xml="yes" dtdprefix="${env.DEPENDENCYFINDER_HOME}/etc">
      <path path="${build.dir}/classes" />
    </dependencyextractor>
  </target>

  <target name="dependencyfinder.report" description="Generates an HTML report from DependencyFinder data.">
    <!-- Create XML files with class2class and package2package info, plus HTML reports. -->
    <taskdef name="dependencyreporter" classname="com.jeantessier.dependencyfinder.ant.DependencyReporter">
      <classpath refid="dependencyfinder.path" />
    </taskdef>

    <xslt style="${env.DEPENDENCYFINDER_HOME}/etc/DependencyGraphToHTML.xsl" 
          in="${dependencyfinder.dir}/all.xml" out="${dependencyfinder.dir}/all/index.html" />
    <dependencyreporter srcfile="${dependencyfinder.dir}/all.xml" destfile="${dependencyfinder.dir}/class2class.xml" 
      c2c="yes" showall="yes" includes="edu/hawaii/" validate="true" xml="yes" dtdprefix="${env.DEPENDENCYFINDER_HOME}/etc" />

    <xslt style="${env.DEPENDENCYFINDER_HOME}/etc/DependencyGraphToHTML.xsl" 
          in="${dependencyfinder.dir}/class2class.xml" out="${dependencyfinder.dir}/class2class/index.html" />
    <dependencyreporter srcfile="${dependencyfinder.dir}/all.xml" destfile="${dependencyfinder.dir}/package2package.xml" 
      p2p="yes" showall="yes" includes="edu/hawaii/" validate="true" xml="yes" dtdprefix="${env.DEPENDENCYFINDER_HOME}/etc" />

    <xslt style="${env.DEPENDENCYFINDER_HOME}/etc/DependencyGraphToHTML.xsl" 
          in="${dependencyfinder.dir}/package2package.xml" out="${dependencyfinder.dir}/package2package/index.html" />
  </target>


  <target name="dependencyfinder.sensor" description="Sends Dependency data to Hackystat using the DependencyFinder sensor.">
    <!-- Define the dependencyfinder sensor taskdef, failing the build if the sensor is not installed. -->
    <available classname="org.hackystat.sensor.dependencyfinder.DependencyFinderSensor" property="dependencyfinder.sensor.available"/>
    <fail unless="dependencyfinder.sensor.available" message="Error: DependencyFinder sensor not installed."/>
    <taskdef name="hacky-dependency" classname="org.hackystat.sensor.dependencyfinder.DependencyFinderSensor" />    

    <hacky-dependency verbose="${hackystat.verbose.mode}"
                      class2ClassFile="${dependencyfinder.dir}/class2class.xml" 
                      package2packageFile="${dependencyfinder.dir}/package2package.xml">
      <fileset dir="${src.dir}">
        <include name="**/*.java"/>
      </fileset>
    </hacky-dependency>

  </target>

The final target, called "hacky-dependency", is the actual sensor target. As you can see, it accepts three attributes and one nested fileset. The attributes are: "verbose", which if set to "true" will generate additional output, "class2ClassFile", which should provide the path to the class dependency XML file, and "package2PackageFile", which should provide the path to the package dependency XML file. The nested fileset should provide the sensor with the set of source files used to generate the dependency data in the XML files.

For more details on these targets, see Section 4.10, “Measurement: Structural coupling with DependencyFinder”, which illustrates the installation and use of DependencyFinder on a sample Java system called StackyHack.

26.11.3. Installation verification

26.11.3.1. Verify verbose mode output

To verify your DependencyFinder sensor installation, invoke the target and check to see that data is sent to the server. Example 26.29, “Example DependencyFinder output” shows the shell output from an example run with verbose= "on" for <hacky-dependency>.

Example 26.29. Example DependencyFinder output

C:\svn-csdl\StackyHack>ant -Dhackystat.verbose.mode=true -f dependencyfinder.build.xml
Buildfile: dependencyfinder.build.xml

compile:

dependencyfinder.tool:
[dependencyextractor] Reading classes from path C:\svn-csdl\StackyHack\build\classes
[dependencyextractor] Saving dependency graph to C:\svn-csdl\StackyHack\build\dependencyfinder\all.xml

dependencyfinder.report:
     [xslt] Processing C:\svn-csdl\StackyHack\build\dependencyfinder\all.xml to C:\svn-csdl\StackyHack\build\dependencyfinder\all\index.html
     [xslt] Loading stylesheet C:\java\DependencyFinder-1.1.0\etc\DependencyGraphToHTML.xsl
[dependencyreporter] Reading graph from C:\svn-csdl\StackyHack\build\dependencyfinder\all.xml
[dependencyreporter] Saving dependency graph to C:\svn-csdl\StackyHack\build\dependencyfinder\class2class.xml
     [xslt] Processing C:\svn-csdl\StackyHack\build\dependencyfinder\class2class.xml to C:\svn-csdl\StackyHack\build\dependencyfinder\class2class\index.html
     [xslt] Loading stylesheet C:\java\DependencyFinder-1.1.0\etc\DependencyGraphToHTML.xsl
[dependencyreporter] Reading graph from C:\svn-csdl\StackyHack\build\dependencyfinder\all.xml
[dependencyreporter] Saving dependency graph to C:\svn-csdl\StackyHack\build\dependencyfinder\package2package.xml
     [xslt] Processing C:\svn-csdl\StackyHack\build\dependencyfinder\package2package.xml to C:\svn-csdl\StackyHack\build\dependencyfinder\package2package\index.html
     [xslt] Loading stylesheet C:\java\DependencyFinder-1.1.0\etc\DependencyGraphToHTML.xsl

dependencyfinder.sensor:
[hacky-dependency] DependencyFinderSensor verbose mode.
[hacky-dependency] Sensor enabled?: true
[hacky-dependency] Processing dependency xml file: C:\svn-csdl\StackyHack\build\dependencyfinder/class2class.xml
[hacky-dependency] Processed Class Dependency: 5
[hacky-dependency] Processing dependency xml file: C:\svn-csdl\StackyHack\build\dependencyfinder/package2package.xml
[hacky-dependency] Processed Package Dependency: 1
[hacky-dependency] Hackystat data on 6 Dependency Finder dependency entries sent to http://hackystat.ics.hawaii.edu/ (0 secs.)

dependencyfinder:

BUILD SUCCESSFUL
Total time: 23 seconds

The DependencyFinder sensor will output a different message if the data was not sent successfully. The data was sent in less than a second, hence the "0 secs." output value.

26.11.3.2. List Sensor Data

Once you verify that DependencyFinder data is being sent from the client using verbose mode, login to your account on your Hackystat server, and use the "List Sensor Data" command on the Extras page to verify that Dependency data for today's date was received by the server for the DependencyFinder tool, as illustrated in Figure 26.17, “ List Sensor Data with DependencyFinder data ”.

Figure 26.17.  List Sensor Data with DependencyFinder data


List Sensor Data with DependencyFinder data

26.11.4. Installation troubleshooting

26.11.4.1. Troubleshooting general client-server problems

The first step in troubleshooting your sensor installation is to verify that your Hackystat host and key settings are valid and that you can contact the Hackystat server, as described in Section 2.4, “HackyInstaller GUI: Setting and verifying the Hackystat host and user key”

26.11.4.2. Checking client-side logging

The DependencyFinder sensor writes out a file called dependency.0.log to the .hackystat/logs directory that can be useful in debugging your installation. Under normal conditions, this file should look similar to Example 26.30, “dependency.0.log file for DependencyFinder sensor”.

Example 26.30. dependency.0.log file for DependencyFinder sensor

Hackystat Version: 6.3.1124 (November 24 2004 12:05:38)
SensorShell started at: 12/03/2004 13:57:01
Type 'help' for a list of commands.
Host: http://hackystat.ics.hawaii.edu/ is available and key is valid.
Defined shell command: Dependency
Defined shell command: Issue
Defined shell command: Perf
Defined shell command: FileMetric
Defined shell command: ReviewIssue
Defined shell command: Activity
Defined shell command: Cli
Defined shell command: ReviewActivity
Defined shell command: Coverage
Defined shell command: UnitTest
Defined shell command: BuffTrans
Defined shell command: Commit
Defined shell command: Build
#> AutoSend [10]
AutoSend OK (set to 10 minutes)
AutoSend enabled every 10 minutes.
Checking for offline data to recover.
No offline data found.
#> Dependency [setTool, DependencyFinder]
setTool OK
#> Dependency [add, class, 1102118221651, edu.hawaii.stack.ClearStack, edu.hawaii.stack.TestClearStack, edu.hawaii.stack.EmptyStackException,edu.hawaii.stack.Stack, ]
Dependency add OK (1 total)
#> Dependency [add, class, 1102118221651, edu.hawaii.stack.EmptyStackException, edu.hawaii.stack.ClearStack,edu.hawaii.stack.Stack,edu.hawaii.stack.TestStack, , ]
Dependency add OK (2 total)
#> Dependency [add, class, 1102118221651, edu.hawaii.stack.Stack, edu.hawaii.stack.ClearStack,edu.hawaii.stack.TestStack, edu.hawaii.stack.EmptyStackException, ]
Dependency add OK (3 total)
#> Dependency [add, class, 1102118221651, edu.hawaii.stack.TestClearStack, , edu.hawaii.stack.ClearStack, ]
Dependency add OK (4 total)
#> Dependency [add, class, 1102118221651, edu.hawaii.stack.TestStack, , edu.hawaii.stack.EmptyStackException,edu.hawaii.stack.Stack, ]
Dependency add OK (5 total)
#> Dependency [add, package, 1102118221823, edu.hawaii.stack, , , ]
Dependency add OK (6 total)
#> send
Sending sensor data (12/03 13:57:02)
  Ping: Ping OK (contacted server http://hackystat.ics.hawaii.edu/ with valid key.)
  Dependency: Send OK (6 entries)
  AutoSend: AutoSend OK ('send' command ignored)
  Issue: Send OK (No entries to send.)
  Perf: Send OK (No entries to send.)
  FileMetric: Send OK (No entries to send.)
  ReviewIssue: Send OK (No entries to send.)
  Activity: Send OK (No entries to send.)
  Cli: Send OK (No entries to send.)
  ReviewActivity: Send OK (No entries to send.)
  Coverage: Send OK (No entries to send.)
  Commit: Send OK (No entries to send.)
  UnitTest: Send OK (No entries to send.)
  BuffTrans: Send OK (No entries to send.)
  Build: Send OK (No entries to send.)

26.11.4.3. Submit a trouble report

If none of the above troubleshooting activities solves your problem, then you should send an email to your Hackystat Administrator to request help. Please include in your email the following information:

  • The output from 'java -version'.

  • The output from 'java -jar sensorshell.jar -verify'.

  • The contents of your sensor.properties file.

  • The contents of the dependency.0.log file.

  • A description of the problem you are having.

26.11.5. Usage tips

26.11.5.1. Integrate DependencyFinder data collection into your development process

You probably don't want to have to invoke "ant dependency" manually each time you want metric data sent to Hackystat. It is better to have the dependency data calculated and sent to Hackystat automatically as a natural course of development. One strategy is to make the dependency target a dependent target of an "install" or "distribution" target so that structural data is recorded each time significant changes occur to the system. This provides a historical record of the structural evolution that can be later used by Hackystat analyses.

26.11.5.2. Disable verbose mode

Set verbose="off" once things are working correctly.

26.11.6. Uninstallation

To disable DependencyFinder sensor data collection temporarily, invoke HackyInstaller, bring up the DependencyFinder configuration window, and uncheck the "Enable DependencyFinder sensor" property, and apply the setting. To permanently uninstall the DependencyFinder sensor, press the "Uninstall" button and remove the DependencyFinder sensor targets from your Ant build.xml files.