SourceForge.net Logo Metrics 1.3.6 - Getting started

Note: This version requires Eclipse 3.1

To access the sourceforge project page click here.

What's new:

I want to thank Guillaume Boissier for doing most of the work on this release. Thanks! I also want to thank Uwe Kubosch for contributing the layered package view. Thanks!

Installation procedure

Run Eclipse, go to Help menu -> Software Updates -> Find and Install ... On the opening dialog choose Search for new features to install. Add a new Remote site with the following url http://metrics.sourceforge.net/update and follow the instructions for installation.

To use the metrics plugin you have to be in a Java or Java Browsing perspective or any other perspective that shows java resources as source folders, packages and compilation units. The simple resource perspective won't do. This makes sense since the metrics are all about counting aspects of your java code.

To start using the Metrics View, use Windows -> Show View -> Other and navigate to the Metrics View, as shown in the next image.

Initially the resulting view will show a brief usage message because no metrics have been calculated yet. To start collecting metrics for a project, right click on the project and from the popup menu select "Metrics->Enable" (or alternatively, use the properties page ).This will tell Eclipse to calculate metrics every time a compile happens. Now that you've enabled a project, the easiest way to calculate all its metrics is to do a full rebuild of that project. The metrics view will indicate the progress of the metrics calculations as they are being performed in the background. When it's all done, the metrics view will look something like this:

Note that any metric shown in blue can be double-clicked to navigate to the resource causing the maximum value for the metric. Since 1.2.0, the metrics table is actualy a table tree, allowing you to expand each metric to show the values at levels below the selected resource. The child elements at each level are sorted in descending metric (maximum) value order.

Preferences

The metrics preferences allow the display order of the metrics to be changed and the metrics database to be cleared (to force recalculation of all metrics). In addition, the toplevel preference page serves as a category for individual metric's preference pages (category id is net.sourceforge.metrics.ui.MetricsPreferencePage).

As of version 1.0.9 of the plugin, the metrics can now trigger warnings that show up in the task view as well as the editors, indicating methods and types for which metrics safe ranges are being violated. The minimum and maximum for each metric can be set in the preferences. This feature is disabled by default, and has to be enabled on the main preference page.

Export to XML

Metrics can be exported to an XML file to be processed with XSL into any kind of report you want. To export metrics, select the scope (project, package, etc.) so it is displayed in the view. Then use the view's toolbar or dropdown menu to select the export function.

Colors

The metrics view can use custom colors for the display of metrics. Three colors are used:

Dependency Analysis

Version 1.1.0 and higher include a graphical dependency analyzer. This view is started from the metrics view menu or toolbar and it only works when a source folder or entire project is selected. It shows a dynamic hyperbolic graph of the package dependencies, which can be zoomed and rotated. Use the radio buttons and scrollbar to manipulate the graph. The red and blue rectangles represent packages, and the edges their dependencies. Example:

The package dependency graph is analyzed for strong components (all nodes reachable from each other, called "tangle" from now on) and those nodes are colored red. Other packages not participating in cycles are colored blue. Right-click on the background of the view to reach the popup menu listing all the tangles found in the dependency graph. If the menu does not list any, you are in good shape and your dependency graph has no cycles. If you select a cycle, only packages involved in it are shown, as in the following image.

The little yellow circle connects all packages involved in the tangle. It shows the number of nodes involved in the tangle and the longest walk. Right-clicking on the tangle center (the yellow circular node) shows a pop-up menu with the last entry labeled "Analyze Details". This option invokes a search using the Eclipse search engine for all types involved in the packages of the tangle. The result is a more detailed dependency graph in which the nodes are types, and the dependencies are between types. The graph only shows dependencies that cross package boundaries. Every connection in this graph connects two classes in different packages. The packages themselves are green rounded rectangles. Analyzing the detail graph is best done with the hyperbolic slider all the way to the left, so there is no curvature in the surface. In this mode, type nodes tend to cluster around their package, but at the same time, they gravitate towards where they are most connected. So if you notice a very long green connection from a package to a type, but that type is located more closely to some other package, perhaps it needs to move to that package, apparently being more closely related to the classes in its vicinity. The next image shows an example of this phenomena.

Notice the Metric and Constants types. These seem closely related to the calculators package, yet they are located in the core package.

In the construction of these graphs, connections between a package and its types is stronger than the connections between types. The connections between types involved in a tangle (red) is stronger than regular connections (blue). Think of the connections as rubber bands with different elasticity.

In large tangle it is sometimes hard to see why all nodes are connected to each other and how. To help with that, The tangle popup menu has a "Find Shortest Path" entry that shows the following dialog:

Headless operation from Ant

Warning : since version 1.3.6 the anttask.jar as been renamed ant-metricstask.jar As of version 1.3.2 the metrics plugin contains some ant tasks that can be used for headless operations as part of a nightly build for example. This section describes how to do this.

Running eclipse without ui on an Ant build file

The following example DOS batch file shows how to run a headless build using eclipse, edit to match your environment:
echo off
setlocal

set JAVA_HOME="c:\program files\jdk141_07" 

set VMARGS="-Xmx256m"

REM The JRE java.exe to be used
set JAVAEXE=%JAVA_HOME%\jre\bin\java.exe"

REM The Eclipse startup.jar
set STARTUPJAR="C:\usr\Eclipse3.1\eclipse\startup.jar"

REM The location of your workspace (does not need to exist)
set WORKSPACE=C:\usr\ecworkspace

if not exist %JAVAEXE% echo ERROR: incorrect java.exe=%JAVAEXE%, edit this file and correct the JAVAEXE envar
if not exist %JAVAEXE% goto done

if not exist %STARTUPJAR% echo ERROR: incorrect startup.jar=%STARTUPJAR%, edit this file and correct the STARTUPJAR envar
if not exist %STARTUPJAR% goto done

:run
@echo on
date /t 
time /t 

%JAVAEXE% %VMARGS% -cp %STARTUPJAR% org.eclipse.core.launcher.Main -noupdate -application org.eclipse.ant.core.antRunner -data %WORKSPACE% -file build.xml %*

date /t 
time /t 

:done
pause
Note that the metrics builder determines it is running headless by checking for the "-noupdate" commandline argument. If it finds there is no UI, it calculates the metrics in the current (foreground) thread instead of queuing them up and forking a background thread to perform the calculations.

Ant tasks provided by this plugin

<eclipse.build>

Convenience task because I did not like the built-in <eclipse.incrementalBuild> task. Not strictly related to metrics calculation and for a large part copied from an example in an article by Barry Searle and Ellen McKay on using Ant with Websphere Studio ApplicationDeveloper.

parameterdescription
projectName (String)Name of the eclipse project to build
buildType (String)One of "incremental", "full" or "auto"
failOnError (boolean)"true" or "false"
errorOut (File)Compiler errors go here
errorFormat (String)One of "txt" or "xml"
Example:

	  <eclipse.build 
	  	ProjectName="net.sourceforge.metrics" 
	  	BuildType="full" 
	  	errorOut="errors.xml" 
	  	errorFormat="xml" 
	  	failOnError="true"/>

<metrics.enable>

Takes only one parameter, projectName and simply enables the metrics for that project if not already enabled. This adds the metrics nature and build command to the .project file.

Example:

	  <metrics.enable projectName="net.sourceforge.metrics"/<

<metrics.export>

parameterdescription
projectName (String)Name of the eclipse project to build
file (File)Metrics get exported to this file
Note that currently only the "metrics-flat-first" export format is supported.

Example:

	  <metrics.export 
	  	projectName="net.sourceforge.metrics" 
	  	file="metrics-metrics.xml"/>

build.xml example

<?xml version="1.0" encoding="UTF-8"?>
<project name="net.sourceforge.metrics" default="build" basedir=".">
	<target name="init">
	   <tstamp/>
	</target>

	<target name="build" depends="init">
	  <eclipse.refreshLocal resource="net.sourceforge.metrics" depth="infinite"/>
	  <metrics.enable projectName="net.sourceforge.metrics"/>
	  <eclipse.build 
	  	ProjectName="net.sourceforge.metrics" 
	  	BuildType="full" 
	  	errorOut="errors.xml" 
	  	errorFormat="xml" 
	  	failOnError="true"/>
	  <metrics.export 
	  	projectName="net.sourceforge.metrics" 
	  	file="metrics-${DSTAMP}-${TSTAMP}.xml"/>
	</target>

</project>

Note

To my surprise, metrics calculate just fine without the project being built by the java builder. If your nightly build does not use eclipse to do the compilation, you can still calculate the metrics using eclipse without incurring a double compilation cycle. Simply remove the the java build command from the .project file in the headless project. Also, only the source folders have to be in the .classpath file since we're not actually compiling anything, and the metrics builder does not use any jars on the classpath anyways.

Metrics - Meanings

The following provide brief descriptions of each metric. In these descriptions, the word "scope" refers to the selected element in the navigator, e.g. a project, source folder, package or compilation unit. I used "Object-Oriented Metrics, measures of Complexity" by Brian Henderson-Sellers, Prentice Hall, 1996 as my primary source of inspiration.

Number of Classes

Total number of classes in the selected scope

Number of Children

Total number of direct subclasses of a class. A class implementing an interface counts as a direct child of that interface

Number of Interfaces

Total number of interfaces in the selected scope

Depth of Inheritance Tree (DIT)

Distance from class Object in the inheritance hierarchy.

Number of Overridden Methods (NORM)

Total number of methods in the selected scope that are overridden from an ancestor class The calculation of NORM can be customized from its preference page, shown below:

Here you can control whether to count abstract methods, methods that call the inherited implementation (through use of super.[same-method] call). Certain methods that are supposed to be overridden can be excluded explicitly (like toString, equals and hashCode).

Number of Methods (NOM)

Total number of methods defined in the selected scope

Number of Fields

Total number of fields defined in the selected scope

Lines of Code

since version 1.3.6 Lines of code has been changed and separated into:
  • TLOC: Total lines of code that will counts non-blank and non-comment lines in a compilation unit. usefull for thoses interested in computed KLOC.
  • MLOC: Method lines of code will counts and sum non-blank and non-comment lines inside method bodies
  • Specialization Index

    Average of the specialization index, defined as NORM * DIT / NOM. This is a class level metric

    McCabe Cyclomatic Complexity

    Counts the number of flows through a piece of code. Each time a branch occurs (if, for, while, do, case, catch and the ?: ternary operator, as well as the && and || conditional logic operators in expressions) this metric is incremented by one. Calculated for methods only. For a full treatment of this metric see
    McCabe.

    Weighted Methods per Class (WMC)

    Sum of the McCabe Cyclomatic Complexity for all methods in a class

    Lack of Cohesion of Methods (LCOM*)

    A measure for the Cohesiveness of a class. Calculated with the Henderson-Sellers method (LCOM*, see page 147). If (m(A) is the number of methods accessing an attribute A, calculate the average of m(A) for all attributes, subtract the number of methods m and divide the result by (1-m). A low value indicates a cohesive class and a value close to 1 indicates a lack of cohesion and suggests the class might better be split into a number of (sub)classes.

    I'm unsure of the usefullness of this metric in Java since it penalizes the proper use of getters and setters as the only methods that directly access an attribute and the other methods using the gettter/setter methods. Perhaps I could alter the implementation to take this into account, assuming standard JavaBean naming conventions.

    The LCOM* metric has it's own preference page, shown below:

    Here you can control whether static fields and static methods should be considered in the calculation of LCOM*.

    Robert C. Martin Suite

    The following are the coupling metrics as defined by Robert Martin in "OO Design Quality Metrics, An Analysis of Dependencies", and more recently in his book named "Agile Software Development, Principles, Patterns and Practices".

    Afferent Coupling (Ca)

    The number of classes outside a package that depend on classes inside the package.

    Efferent Coupling (Ce)

    The number of classes inside a package that depend on classes outside the package.

    Instability (I)

    Ce / (Ca + Ce)

    Abstractness (A)

    The number of abstract classes (and interfaces) divided by the total number of types in a package

    Normalized Distance from Main Sequence (Dn

    | A + I - 1 |, this number should be small, close to zero for good packaging design.

    Licenses and Credits

    The metrics plugin is CPL1.0, the same license as Eclipse itself. It uses the following open source code by others, without these packages, this tool would not have been possible. Thanks for all the good work! The source to any modifications is available in the metricssrc.zip.

    JDBM

    I use the JDBM package as the persistence layer for the metrics. Very cool package! I use the HTree (persistent hashtable) with a MRU Cache of size 500. JDBM carries the BSD license and can be obtained from
    jdbm.sourceforge.net.

    Touchgraph

    The (AWT) graphing tool used for the dependency graphs. Made some minor modifications to add popup menu entries and embedd it in Eclipse. Touch graph was developed by Alexander Shapiro, and is LGPL. Visit http://www.touchgraph.com for more cool examples and more details.

    Classycle

    The detection of the tangles (strong components) in the dependency graph is based on code by Franz-Josef Elmer, classycle v 0.9, which implements Tarjan's algorithm. This code is distributed under a BSD like license. See http://sourceforge.net/projects/classycle for details and updates.