421 lines
45 KiB
HTML
421 lines
45 KiB
HTML
<html><head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>Chapter 12. Data mining of bugs with FindBugs™</title><meta name="generator" content="DocBook XSL Stylesheets V1.76.1"><link rel="home" href="index.html" title="FindBugs™ Manual"><link rel="up" href="index.html" title="FindBugs™ Manual"><link rel="prev" href="rejarForAnalysis.html" title="Chapter 11. Using rejarForAnalysis"><link rel="next" href="license.html" title="Chapter 13. License"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 12. Data mining of bugs with <span class="application">FindBugs</span>™</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="rejarForAnalysis.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="license.html">Next</a></td></tr></table><hr></div><div class="chapter" title="Chapter 12. Data mining of bugs with FindBugs™"><div class="titlepage"><div><div><h2 class="title"><a name="datamining"></a>Chapter 12. Data mining of bugs with <span class="application">FindBugs</span>™</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="datamining.html#commands">1. Commands</a></span></dt><dt><span class="sect1"><a href="datamining.html#examples">2. Examples</a></span></dt><dt><span class="sect1"><a href="datamining.html#antexample">3. Ant example</a></span></dt></dl></div><p>
|
|
FindBugs incorporates an ability to perform sophisticated queries on bug
|
|
databases and track warnings across multiple versions of code being
|
|
studied, allowing you to do things such as seeing when a bug was first introduced, examining
|
|
just the warnings that have been introduced since the last release, or graphing the number
|
|
of infinite recursive loops in your code over time.</p><p>
|
|
These techniques all depend upon the XML format used by FindBugs for storing warnings.
|
|
These XML files usually contain just the warnings from one particular analysis run, but
|
|
they can also store the results from analyzing a sequence of software builds or versions.
|
|
</p><p>
|
|
Any FindBugs XML bug database contains a version name and timestamp.
|
|
FindBugs tries to compute a timestamp from the timestamps of the files that
|
|
are analyzed (e.g., the timestamp is intended to be the time the class files
|
|
were generated, not analyzed). Each bug database also contains a version name.
|
|
Both the version name and timestamp can be set manually using the
|
|
<span class="command"><strong>setBugDatabaseInfo</strong></span> (<a class="xref" href="datamining.html#setBugDatabaseInfo" title="1.7. setBugDatabaseInfo">Section 1.7, “setBugDatabaseInfo”</a>) command.
|
|
</p><p>A multiversion bug database assigns a sequence number to each version of
|
|
the analyzed code. These sequence numbers are simply successive integers,
|
|
starting at 0 (e.g., a bug database for 4 versions of the code will contain
|
|
versions 0..3). The bug database will also record the name and timestamp for
|
|
each version. The <span class="command"><strong>filterBugs</strong></span> command allows you to refer
|
|
to a version by sequence number, name or timestamp.</p><p>
|
|
You can take a sequence (or pair) of single version bug databases and create
|
|
from them a multiversion bug database, or combine a multiversion bug database
|
|
with a sequence of later single-version bug databases.</p><p>
|
|
Some of these commands can be invoked as ant tasks. See below for specifics
|
|
on how to invoke them and what attributes and arguments they take. All of
|
|
the examples assume that the <code class="literal">findbugs.lib</code>
|
|
<code class="literal">refid</code> is set correctly. Here is one way to set it:
|
|
</p><pre class="programlisting">
|
|
|
|
<!-- findbugs task definition -->
|
|
<property name="findbugs.home" value="/your/path/to/findbugs" />
|
|
<path id="findbugs.lib">
|
|
<fileset dir="${findbugs.home}/lib">
|
|
<include name="findbugs-ant.jar"/>
|
|
</fileset>
|
|
</path>
|
|
|
|
</pre><div class="sect1" title="1. Commands"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="commands"></a>1. Commands</h2></div></div></div><p>
|
|
All tools for FindBugs data mining are can be invoked from the command line,
|
|
and some of the more useful tools can also be invoked from an
|
|
ant build file.</p><p>
|
|
Briefly, the command-line tools are:</p><div class="variablelist"><dl><dt><span class="term"><span class="command"><strong><a class="link" href="datamining.html#unionBugs" title="1.1. unionBugs">unionBugs</a></strong></span></span></dt><dd><p>
|
|
combine the results from separate analysis of disjoint
|
|
classes
|
|
</p></dd><dt><span class="term"><span class="command"><strong><a class="link" href="datamining.html#computeBugHistory" title="1.2. computeBugHistory">computeBugHistory</a></strong></span></span></dt><dd><p>Merge bug warnings from multiple versions of
|
|
analyzed code into
|
|
a single multiversion bug database. This can either be used
|
|
to add more versions to an existing multiversion database,
|
|
or to create a multiversion database from a sequence of single version
|
|
bug warning databases.</p></dd><dt><span class="term"><span class="command"><strong><a class="link" href="datamining.html#setBugDatabaseInfo" title="1.7. setBugDatabaseInfo">setBugDatabaseInfo</a></strong></span></span></dt><dd><p>Set information such as the revision name or
|
|
timestamp in an XML bug database</p></dd><dt><span class="term"><span class="command"><strong><a class="link" href="datamining.html#listBugDatabaseInfo" title="1.8. listBugDatabaseInfo">listBugDatabaseInfo</a></strong></span></span></dt><dd><p>List information such as the revision name and
|
|
timestamp for a list of XML bug databases</p></dd><dt><span class="term"><span class="command"><strong><a class="link" href="datamining.html#filterBugs" title="1.3. filterBugs">filterBugs</a></strong></span></span></dt><dd><p>Select a subset of a bug database</p></dd><dt><span class="term"><span class="command"><strong><a class="link" href="datamining.html#mineBugHistory" title="1.4. mineBugHistory">mineBugHistory</a></strong></span></span></dt><dd><p>Generate a tabular listing of the number of warnings in each
|
|
version of a multiversion bug database</p></dd><dt><span class="term"><span class="command"><strong><a class="link" href="datamining.html#defectDensity" title="1.5. defectDensity">defectDensity</a></strong></span></span></dt><dd><p>List information about defect density
|
|
(warnings per 1000 NCSS)
|
|
for the entire project and each class and package</p></dd><dt><span class="term"><span class="command"><strong><a class="link" href="datamining.html#convertXmlToText" title="1.6. convertXmlToText">convertXmlToText</a></strong></span></span></dt><dd><p>Convert bug warnings in XML format to
|
|
a textual one-line-per-bug format, or to HTML</p></dd></dl></div><div class="sect2" title="1.1. unionBugs"><div class="titlepage"><div><div><h3 class="title"><a name="unionBugs"></a>1.1. unionBugs</h3></div></div></div><p>
|
|
If you have, for example, separately analyzing each jar file used in an application,
|
|
you can use this command to combine the separately generated xml bug warning files into
|
|
a single file containing all of the warnings.</p><p>Do <span class="emphasis"><em>not</em></span> use this command to combine results from analyzing different versions of the same
|
|
file; use <span class="command"><strong>computeBugHistory</strong></span> instead.</p><p>Specify the xml files on the command line. The result is sent to standard output.</p></div><div class="sect2" title="1.2. computeBugHistory"><div class="titlepage"><div><div><h3 class="title"><a name="computeBugHistory"></a>1.2. computeBugHistory</h3></div></div></div><p>Use this command to generate a bug database containing information from different builds or versions
|
|
of software you are analyzing.
|
|
History is taken from the first file provided as input; any following
|
|
files should be single version bug databases (if they contain history, the history in those
|
|
files will be ignored).</p><p>By default, output is written to the standard output.
|
|
</p><p>This functionality may also can be accessed from ant.
|
|
First create a taskdef for <span class="command"><strong>computeBugHistory</strong></span> in your
|
|
build file:
|
|
</p><pre class="programlisting">
|
|
|
|
<taskdef name="computeBugHistory" classname="edu.umd.cs.findbugs.anttask.ComputeBugHistoryTask">
|
|
<classpath refid="findbugs.lib" />
|
|
</taskdef>
|
|
|
|
</pre><p>Attributes for this ant task are listed in the following table.
|
|
To specify input files, nest them inside with a
|
|
<code class="literal"><datafile></code> element. For example:
|
|
</p><pre class="programlisting">
|
|
|
|
<computeBugHistory home="${findbugs.home}" ...>
|
|
<datafile name="analyze1.xml"/>
|
|
<datafile name="analyze2.xml"/>
|
|
</computeBugHistory>
|
|
|
|
</pre><div class="table"><a name="computeBugHistoryTable"></a><p class="title"><b>Table 12.1. Options for computeBugHistory command</b></p><div class="table-contents"><table summary="Options for computeBugHistory command" border="1"><colgroup><col><col><col></colgroup><thead><tr><th align="left">Command-line option</th><th align="left">Ant attribute</th><th align="left">Meaning</th></tr></thead><tbody><tr><td align="left">-output <file></td><td align="left">output="<file>"</td><td align="left">save output in the named file (may also be an input file)</td></tr><tr><td align="left">-overrideRevisionNames[:truth]</td><td align="left">overrideRevisionNames="[true|false]"</td><td align="left">override revision names for each version with names computed from the filenames</td></tr><tr><td align="left">-noPackageMoves[:truth]</td><td align="left">noPackageMoves="[true|false]"</td><td align="left">if a class has moved to another package, treat warnings in that class as seperate</td></tr><tr><td align="left">-preciseMatch[:truth]</td><td align="left">preciseMatch="[true|false]"</td><td align="left">require bug patterns to match precisely</td></tr><tr><td align="left">-precisePriorityMatch[:truth]</td><td align="left">precisePriorityMatch="[true|false]"</td><td align="left">consider two warnings as the same only if priorities match exactly</td></tr><tr><td align="left">-quiet[:truth]</td><td align="left">quiet="[true|false]"</td><td align="left">don't generate any output to standard out unless there is an error</td></tr><tr><td align="left">-withMessages[:truth]</td><td align="left">withMessages="[true|false]"</td><td align="left">include human-readable messages describing the warnings in XML output</td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" title="1.3. filterBugs"><div class="titlepage"><div><div><h3 class="title"><a name="filterBugs"></a>1.3. filterBugs</h3></div></div></div><p>This command is used to select a subset of warnings from a FindBugs XML warning file
|
|
and write the selected subset to a new FindBugs warning file.</p><p>
|
|
This command takes a sequence of options, and either zero, one or two
|
|
filenames of findbugs xml bug files on the command line.</p><p>If no file names are provided, the command reads from standard input
|
|
and writes to standard output. If one file name is provided,
|
|
it reads from the file and writes to standard output.
|
|
If two file names are provided, it reads from the first and writes the output
|
|
to the second file name.</p><p>This functionality may also can be accessed from ant.
|
|
First create a taskdef for <span class="command"><strong>filterBugs</strong></span> in your
|
|
build file:
|
|
</p><pre class="programlisting">
|
|
|
|
<taskdef name="filterBugs" classname="edu.umd.cs.findbugs.anttask.FilterBugsTask">
|
|
<classpath refid="findbugs.lib" />
|
|
</taskdef>
|
|
|
|
</pre><p>Attributes for this ant task are listed in the following table.
|
|
To specify an input file either use the input attribute or nest it inside
|
|
the ant call with a <code class="literal"><datafile></code> element. For example:
|
|
</p><pre class="programlisting">
|
|
|
|
<filterBugs home="${findbugs.home}" ...>
|
|
<datafile name="analyze.xml"/>
|
|
</filterBugs>
|
|
|
|
</pre><div class="table"><a name="filterOptionsTable"></a><p class="title"><b>Table 12.2. Options for filterBugs command</b></p><div class="table-contents"><table summary="Options for filterBugs command" border="1"><colgroup><col><col><col></colgroup><thead><tr><th align="left">Command-line option</th><th align="left">Ant attribute</th><th align="left">Meaning</th></tr></thead><tbody><tr><td align="left"> </td><td align="left">input="<file>"</td><td align="left">use file as input</td></tr><tr><td align="left"> </td><td align="left">output="<file>"</td><td align="left">output results to file</td></tr><tr><td align="left">-not</td><td align="left">not="[true|false]"</td><td align="left">reverse (all) switches for the filter</td></tr><tr><td align="left">-withSource[:truth]</td><td align="left">withSource="[true|false]"</td><td align="left">only warnings for switch source is available</td></tr><tr><td align="left">-exclude <filter file></td><td align="left">exclude="<filter file>"</td><td align="left">exclude bugs matching given filter</td></tr><tr><td align="left">-include <filter file></td><td align="left">include="<filter file>"</td><td align="left">include only bugs matching given filter</td></tr><tr><td align="left">-annotation <text></td><td align="left">annotation="<text>"</td><td align="left">allow only warnings containing this text in a manual annotation</td></tr><tr><td align="left">-after <when></td><td align="left">after="<when>"</td><td align="left">allow only warnings that first occurred after this version</td></tr><tr><td align="left">-before <when></td><td align="left">before="<when>"</td><td align="left">allow only warnings that first occurred before this version</td></tr><tr><td align="left">-first <when></td><td align="left">first="<when>"</td><td align="left">allow only warnings that first occurred in this version</td></tr><tr><td align="left">-last <when></td><td align="left">last="<when>"</td><td align="left">allow only warnings that last occurred in this version</td></tr><tr><td align="left">-fixed <when></td><td align="left">fixed="<when>"</td><td align="left">allow only warnings that last occurred in the previous version (clobbers <code class="option">-last</code>)</td></tr><tr><td align="left">-present <when></td><td align="left">present="<when>"</td><td align="left">allow only warnings present in this version</td></tr><tr><td align="left">-absent <when></td><td align="left">absent="<when>"</td><td align="left">allow only warnings absent in this version</td></tr><tr><td align="left">-active[:truth]</td><td align="left">active="[true|false]"</td><td align="left">allow only warnings alive in the last sequence number</td></tr><tr><td align="left">-introducedByChange[:truth]</td><td align="left">introducedByChange="[true|false]"</td><td align="left">allow only warnings introduced by a change of an existing class</td></tr><tr><td align="left">-removedByChange[:truth]</td><td align="left">removedByChange="[true|false]"</td><td align="left">allow only warnings removed by a change of a persisting class</td></tr><tr><td align="left">-newCode[:truth]</td><td align="left">newCode="[true|false]"</td><td align="left">allow only warnings introduced by the addition of a new class</td></tr><tr><td align="left">-removedCode[:truth]</td><td align="left">removedCode="[true|false]"</td><td align="left">allow only warnings removed by removal of a class</td></tr><tr><td align="left">-priority <level></td><td align="left">priority="<level>"</td><td align="left">allow only warnings with this priority or higher</td></tr><tr><td align="left">-class <pattern></td><td align="left">class="<class>"</td><td align="left">allow only bugs whose primary class name matches this pattern</td></tr><tr><td align="left">-bugPattern <pattern></td><td align="left">bugPattern="<pattern>"</td><td align="left">allow only bugs whose type matches this pattern</td></tr><tr><td align="left">-category <category></td><td align="left">category="<category>"</td><td align="left">allow only warnings with a category that starts with this string</td></tr><tr><td align="left">-designation <designation></td><td align="left">designation="<designation>"</td><td align="left">allow only warnings with this designation (e.g., -designation SHOULD_FIX)</td></tr><tr><td align="left">-withMessages[:truth] </td><td align="left">withMessages="[true|false]"</td><td align="left">the generated XML should contain textual messages</td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" title="1.4. mineBugHistory"><div class="titlepage"><div><div><h3 class="title"><a name="mineBugHistory"></a>1.4. mineBugHistory</h3></div></div></div><p>This command generates a table containing counts of the numbers of warnings
|
|
in each version of a multiversion bug database.</p><p>This functionality may also can be accessed from ant.
|
|
First create a taskdef for <span class="command"><strong>mineBugHistory</strong></span> in your
|
|
build file:
|
|
</p><pre class="programlisting">
|
|
|
|
<taskdef name="mineBugHistory" classname="edu.umd.cs.findbugs.anttask.MineBugHistoryTask">
|
|
<classpath refid="findbugs.lib" />
|
|
</taskdef>
|
|
|
|
</pre><p>Attributes for this ant task are listed in the following table.
|
|
To specify an input file either use the <code class="literal">input</code>
|
|
attribute or nest it inside the ant call with a
|
|
<code class="literal"><datafile></code> element. For example:
|
|
</p><pre class="programlisting">
|
|
|
|
<mineBugHistory home="${findbugs.home}" ...>
|
|
<datafile name="analyze.xml"/>
|
|
</mineBugHistory>
|
|
|
|
</pre><div class="table"><a name="mineBugHistoryOptionsTable"></a><p class="title"><b>Table 12.3. Options for mineBugHistory command</b></p><div class="table-contents"><table summary="Options for mineBugHistory command" border="1"><colgroup><col><col><col></colgroup><thead><tr><th align="left">Command-line option</th><th align="left">Ant attribute</th><th align="left">Meaning</th></tr></thead><tbody><tr><td align="left"> </td><td align="left">input="<file>"</td><td align="left">use file as input</td></tr><tr><td align="left"> </td><td align="left">output="<file>"</td><td align="left">write output to file</td></tr><tr><td align="left">-formatDates</td><td align="left">formatDates="[true|false]"</td><td align="left">render dates in textual form</td></tr><tr><td align="left">-noTabs</td><td align="left">noTabs="[true|false]"</td><td align="left">delimit columns with groups of spaces instead of tabs (see below)</td></tr><tr><td align="left">-summary</td><td align="left">summary="[true|false]"</td><td align="left">output terse summary of changes over the last ten entries</td></tr></tbody></table></div></div><br class="table-break"><p>
|
|
The <code class="option">-noTabs</code> output can be easier to read from a shell
|
|
with a fixed-width font.
|
|
Because numeric columns are right-justified, spaces may precede the
|
|
first column value. This option also causes <code class="option">-formatDates</code>
|
|
to render dates in terser format without embedded whitespace.
|
|
</p><p>The table is a tab-separated (barring <code class="option">-noTabs</code>)
|
|
table with the following columns:</p><div class="table"><a name="mineBugHistoryColumns"></a><p class="title"><b>Table 12.4. Columns in mineBugHistory output</b></p><div class="table-contents"><table summary="Columns in mineBugHistory output" border="1"><colgroup><col><col></colgroup><thead><tr><th align="left">Title</th><th align="left">Meaning</th></tr></thead><tbody><tr><td align="left">seq</td><td align="left">Sequence number (successive integers, starting at 0)</td></tr><tr><td align="left">version</td><td align="left">Version name</td></tr><tr><td align="left">time</td><td align="left">Release timestamp</td></tr><tr><td align="left">classes</td><td align="left">Number of classes analyzed</td></tr><tr><td align="left">NCSS</td><td align="left">Non Commenting Source Statements</td></tr><tr><td align="left">added</td><td align="left">Count of new warnings for a class that existed in the previous version</td></tr><tr><td align="left">newCode</td><td align="left">Count of new warnings for a class that did not exist in the previous version</td></tr><tr><td align="left">fixed</td><td align="left">Count of warnings removed from a class that remains in the current version</td></tr><tr><td align="left">removed</td><td align="left">Count of warnings in the previous version for a class that is not present in the current version</td></tr><tr><td align="left">retained</td><td align="left">Count of warnings that were in both the previous and current version</td></tr><tr><td align="left">dead</td><td align="left">Warnings that were present in earlier versions but in neither the current version or the immediately preceeding version</td></tr><tr><td align="left">active</td><td align="left">Total warnings present in the current version</td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" title="1.5. defectDensity"><div class="titlepage"><div><div><h3 class="title"><a name="defectDensity"></a>1.5. defectDensity</h3></div></div></div><p>
|
|
This command lists information about defect density (warnings per 1000 NCSS) for the entire project and each class and package.
|
|
It can either be invoked with no files specified on the command line (in which case it reads from standard input)
|
|
or with one file specified on the command line.</p><p>It generates a table with the following columns, and with one
|
|
row for the entire project, and one row for each package or class that contains at least
|
|
4 warnings.</p><div class="table"><a name="defectDensityColumns"></a><p class="title"><b>Table 12.5. Columns in defectDensity output</b></p><div class="table-contents"><table summary="Columns in defectDensity output" border="1"><colgroup><col><col></colgroup><thead><tr><th align="left">Title</th><th align="left">Meaning</th></tr></thead><tbody><tr><td align="left">kind</td><td align="left">project, package or class</td></tr><tr><td align="left">name</td><td align="left">The name of the project, package or class</td></tr><tr><td align="left">density</td><td align="left">Number of warnings generated per 1000 lines of NCSS.</td></tr><tr><td align="left">bugs</td><td align="left">Number of warnings</td></tr><tr><td align="left">NCSS</td><td align="left">Calculated number of NCSS</td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" title="1.6. convertXmlToText"><div class="titlepage"><div><div><h3 class="title"><a name="convertXmlToText"></a>1.6. convertXmlToText</h3></div></div></div><p>
|
|
This command converts a warning collection in XML format to a text
|
|
format with one line per warning, or to HTML.
|
|
</p><p>This functionality may also can be accessed from ant.
|
|
First create a taskdef for <span class="command"><strong>convertXmlToText</strong></span> in your
|
|
build file:
|
|
</p><pre class="programlisting">
|
|
|
|
<taskdef name="convertXmlToText" classname="edu.umd.cs.findbugs.anttask.ConvertXmlToTextTask">
|
|
<classpath refid="findbugs.lib" />
|
|
</taskdef>
|
|
|
|
</pre><p>Attributes for this ant task are listed in the following table.</p><div class="table"><a name="convertXmlToTextTable"></a><p class="title"><b>Table 12.6. Options for convertXmlToText command</b></p><div class="table-contents"><table summary="Options for convertXmlToText command" border="1"><colgroup><col><col><col></colgroup><thead><tr><th align="left">Command-line option</th><th align="left">Ant attribute</th><th align="left">Meaning</th></tr></thead><tbody><tr><td align="left"> </td><td align="left">input="<filename>"</td><td align="left">use file as input</td></tr><tr><td align="left"> </td><td align="left">output="<filename>"</td><td align="left">output results to file</td></tr><tr><td align="left">-longBugCodes</td><td align="left">longBugCodes="[true|false]"</td><td align="left">use the full bug pattern code instead of two-letter abbreviation</td></tr><tr><td align="left"> </td><td align="left">format="text"</td><td align="left">generate plain text output with one bug per line (command-line default)</td></tr><tr><td align="left">-html[:stylesheet]</td><td align="left">format="html:<stylesheet>"</td><td align="left">generate output with specified stylesheet (see below), or default.xsl if unspecified</td></tr></tbody></table></div></div><br class="table-break"><p>
|
|
You may specify plain.xsl, default.xsl, fancy.xsl, fancy-hist.xsl,
|
|
or your own XSL stylesheet for the -html/format option.
|
|
Despite the name of this option, you may specify
|
|
a stylesheet that emits something other than html.
|
|
When applying a stylesheet other than those included
|
|
with FindBugs (listed above), the -html/format option should be used
|
|
with a path or URL to the stylesheet.
|
|
</p></div><div class="sect2" title="1.7. setBugDatabaseInfo"><div class="titlepage"><div><div><h3 class="title"><a name="setBugDatabaseInfo"></a>1.7. setBugDatabaseInfo</h3></div></div></div><p>
|
|
This command sets meta-information in a specified warning collection.
|
|
It takes the following options:
|
|
</p><p>This functionality may also can be accessed from ant.
|
|
First create a taskdef for <span class="command"><strong>setBugDatabaseInfo</strong></span> in your
|
|
build file:
|
|
</p><pre class="programlisting">
|
|
|
|
<taskdef name="setBugDatabaseInfo" classname="edu.umd.cs.findbugs.anttask.SetBugDatabaseInfoTask">
|
|
<classpath refid="findbugs.lib" />
|
|
</taskdef>
|
|
|
|
</pre><p>Attributes for this ant task are listed in the following table.
|
|
To specify an input file either use the <code class="literal">input</code>
|
|
attribute or nest it inside the ant call with a
|
|
<code class="literal"><datafile></code> element. For example:
|
|
</p><pre class="programlisting">
|
|
|
|
<setBugDatabaseInfo home="${findbugs.home}" ...>
|
|
<datafile name="analyze.xml"/>
|
|
</setBugDatabaseInfo>
|
|
|
|
</pre><div class="table"><a name="setBugDatabaseInfoOptions"></a><p class="title"><b>Table 12.7. setBugDatabaseInfo Options</b></p><div class="table-contents"><table summary="setBugDatabaseInfo Options" border="1"><colgroup><col><col><col></colgroup><thead><tr><th align="left">Command-line option</th><th align="left">Ant attribute</th><th align="left">Meaning</th></tr></thead><tbody><tr><td align="left"> </td><td align="left">input="<file>"</td><td align="left">use file as input</td></tr><tr><td align="left"> </td><td align="left">output="<file>"</td><td align="left">write output to file</td></tr><tr><td align="left">-name <name></td><td align="left">name="<name>"</td><td align="left">set name for (last) revision</td></tr><tr><td align="left">-timestamp <when></td><td align="left">timestamp="<when>"</td><td align="left">set timestamp for (last) revision</td></tr><tr><td align="left">-source <directory></td><td align="left">source="<directory>"</td><td align="left">add specified directory to the source search path</td></tr><tr><td align="left">-findSource <directory></td><td align="left">findSource="<directory>"</td><td align="left">find and add all relevant source directions contained within specified directory</td></tr><tr><td align="left">-suppress <filter file></td><td align="left">suppress="<filter file>"</td><td align="left">suppress warnings matched by this file (replaces previous suppressions)</td></tr><tr><td align="left">-withMessages</td><td align="left">withMessages="[true|false]"</td><td align="left">add textual messages to XML</td></tr><tr><td align="left">-resetSource</td><td align="left">resetSource="[true|false]"</td><td align="left">remove all source search paths</td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" title="1.8. listBugDatabaseInfo"><div class="titlepage"><div><div><h3 class="title"><a name="listBugDatabaseInfo"></a>1.8. listBugDatabaseInfo</h3></div></div></div><p>This command takes a list of zero or more xml bug database filenames on the command line.
|
|
If zero file names are provided, it reads from standard input and does not generate
|
|
a table header.</p><p>There is only one option: <code class="option">-formatDates</code> renders dates
|
|
in textual form.
|
|
</p><p>The output is a table one row per bug database and the following columns:</p><div class="table"><a name="listBugDatabaseInfoColumns"></a><p class="title"><b>Table 12.8. listBugDatabaseInfo Columns</b></p><div class="table-contents"><table summary="listBugDatabaseInfo Columns" border="1"><colgroup><col><col></colgroup><thead><tr><th align="left">Column</th><th align="left">Meaning</th></tr></thead><tbody><tr><td align="left">version</td><td align="left">version name</td></tr><tr><td align="left">time</td><td align="left">Release timestamp</td></tr><tr><td align="left">classes</td><td align="left">Number of classes analyzed</td></tr><tr><td align="left">NCSS</td><td align="left">Non Commenting Source Statements analyzed</td></tr><tr><td align="left">total</td><td align="left">Total number of warnings of all kinds</td></tr><tr><td align="left">high</td><td align="left">Total number of high priority warnings of all kinds</td></tr><tr><td align="left">medium</td><td align="left">Total number of medium/normal priority warnings of all kinds</td></tr><tr><td align="left">low</td><td align="left">Total number of low priority warnings of all kinds</td></tr><tr><td align="left">filename</td><td align="left">filename of database</td></tr></tbody></table></div></div><br class="table-break"></div></div><div class="sect1" title="2. Examples"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="examples"></a>2. Examples</h2></div></div></div><div class="sect2" title="2.1. Mining history using proveded shell scrips"><div class="titlepage"><div><div><h3 class="title"><a name="unixscriptsexamples"></a>2.1. Mining history using proveded shell scrips</h3></div></div></div><p>In all of the following, the commands are given in a directory that contains
|
|
directories jdk1.6.0-b12, jdk1.6.0-b13, ..., jdk1.6.0-b60.</p><p>You can use the command:</p><pre class="screen">
|
|
computeBugHistory jdk1.6.0-b* | filterBugs -bugPattern IL_ | mineBugHistory -formatDates
|
|
</pre><p>to generate the following output:</p><pre class="screen">
|
|
seq version time classes NCSS added newCode fixed removed retained dead active
|
|
0 jdk1.6.0-b12 "Thu Nov 11 09:07:20 EST 2004" 13128 811569 0 4 0 0 0 0 4
|
|
1 jdk1.6.0-b13 "Thu Nov 18 06:02:06 EST 2004" 13128 811570 0 0 0 0 4 0 4
|
|
2 jdk1.6.0-b14 "Thu Dec 02 06:12:26 EST 2004" 13145 811786 0 0 2 0 2 0 2
|
|
3 jdk1.6.0-b15 "Thu Dec 09 06:07:04 EST 2004" 13174 811693 0 0 1 0 1 2 1
|
|
4 jdk1.6.0-b16 "Thu Dec 16 06:21:28 EST 2004" 13175 811715 0 0 0 0 1 3 1
|
|
5 jdk1.6.0-b17 "Thu Dec 23 06:27:22 EST 2004" 13176 811974 0 0 0 0 1 3 1
|
|
6 jdk1.6.0-b19 "Thu Jan 13 06:41:16 EST 2005" 13176 812011 0 0 0 0 1 3 1
|
|
7 jdk1.6.0-b21 "Thu Jan 27 05:57:52 EST 2005" 13177 812173 0 0 0 0 1 3 1
|
|
8 jdk1.6.0-b23 "Thu Feb 10 05:44:36 EST 2005" 13179 812188 0 0 0 0 1 3 1
|
|
9 jdk1.6.0-b26 "Thu Mar 03 06:04:02 EST 2005" 13199 811770 0 0 0 0 1 3 1
|
|
10 jdk1.6.0-b27 "Thu Mar 10 04:48:38 EST 2005" 13189 812440 0 0 0 0 1 3 1
|
|
11 jdk1.6.0-b28 "Thu Mar 17 02:54:22 EST 2005" 13185 812056 0 0 0 0 1 3 1
|
|
12 jdk1.6.0-b29 "Thu Mar 24 03:09:20 EST 2005" 13117 809468 0 0 0 0 1 3 1
|
|
13 jdk1.6.0-b30 "Thu Mar 31 02:53:32 EST 2005" 13118 809501 0 0 0 0 1 3 1
|
|
14 jdk1.6.0-b31 "Thu Apr 07 03:00:14 EDT 2005" 13117 809572 0 0 0 0 1 3 1
|
|
15 jdk1.6.0-b32 "Thu Apr 14 02:56:56 EDT 2005" 13169 811096 0 0 0 0 1 3 1
|
|
16 jdk1.6.0-b33 "Thu Apr 21 02:46:22 EDT 2005" 13187 811942 0 0 0 0 1 3 1
|
|
17 jdk1.6.0-b34 "Thu Apr 28 02:49:00 EDT 2005" 13195 813488 0 1 0 0 1 3 2
|
|
18 jdk1.6.0-b35 "Thu May 05 02:49:04 EDT 2005" 13457 829837 0 0 0 0 2 3 2
|
|
19 jdk1.6.0-b36 "Thu May 12 02:59:46 EDT 2005" 13462 831278 0 0 0 0 2 3 2
|
|
20 jdk1.6.0-b37 "Thu May 19 02:55:08 EDT 2005" 13464 831971 0 0 0 0 2 3 2
|
|
21 jdk1.6.0-b38 "Thu May 26 03:08:16 EDT 2005" 13564 836565 0 0 0 0 2 3 2
|
|
22 jdk1.6.0-b39 "Fri Jun 03 03:10:48 EDT 2005" 13856 849992 0 1 0 0 2 3 3
|
|
23 jdk1.6.0-b40 "Thu Jun 09 03:30:28 EDT 2005" 15972 959619 0 2 0 0 3 3 5
|
|
24 jdk1.6.0-b41 "Thu Jun 16 03:19:22 EDT 2005" 15972 959619 0 0 0 0 5 3 5
|
|
25 jdk1.6.0-b42 "Fri Jun 24 03:38:54 EDT 2005" 15966 958581 0 0 0 0 5 3 5
|
|
26 jdk1.6.0-b43 "Thu Jul 14 03:09:34 EDT 2005" 16041 960544 0 0 0 0 5 3 5
|
|
27 jdk1.6.0-b44 "Thu Jul 21 03:05:54 EDT 2005" 16041 960547 0 0 0 0 5 3 5
|
|
28 jdk1.6.0-b45 "Thu Jul 28 03:26:10 EDT 2005" 16037 960606 0 0 1 0 4 3 4
|
|
29 jdk1.6.0-b46 "Thu Aug 04 03:02:48 EDT 2005" 15936 951355 0 0 0 0 4 4 4
|
|
30 jdk1.6.0-b47 "Thu Aug 11 03:18:56 EDT 2005" 15964 952387 0 0 1 0 3 4 3
|
|
31 jdk1.6.0-b48 "Thu Aug 18 08:10:40 EDT 2005" 15970 953421 0 0 0 0 3 5 3
|
|
32 jdk1.6.0-b49 "Thu Aug 25 03:24:38 EDT 2005" 16048 958940 0 0 0 0 3 5 3
|
|
33 jdk1.6.0-b50 "Thu Sep 01 01:52:40 EDT 2005" 16287 974937 1 0 0 0 3 5 4
|
|
34 jdk1.6.0-b51 "Thu Sep 08 01:55:36 EDT 2005" 16362 979377 0 0 0 0 4 5 4
|
|
35 jdk1.6.0-b52 "Thu Sep 15 02:04:08 EDT 2005" 16477 979399 0 0 0 0 4 5 4
|
|
36 jdk1.6.0-b53 "Thu Sep 22 02:00:28 EDT 2005" 16019 957900 0 0 1 0 3 5 3
|
|
37 jdk1.6.0-b54 "Thu Sep 29 01:54:34 EDT 2005" 16019 957900 0 0 0 0 3 6 3
|
|
38 jdk1.6.0-b55 "Thu Oct 06 01:54:14 EDT 2005" 16051 959014 0 0 0 0 3 6 3
|
|
39 jdk1.6.0-b56 "Thu Oct 13 01:54:12 EDT 2005" 16211 970835 0 0 0 0 3 6 3
|
|
40 jdk1.6.0-b57 "Thu Oct 20 01:55:26 EDT 2005" 16279 971627 0 0 0 0 3 6 3
|
|
41 jdk1.6.0-b58 "Thu Oct 27 01:56:30 EDT 2005" 16283 971945 0 0 0 0 3 6 3
|
|
42 jdk1.6.0-b59 "Thu Nov 03 01:56:58 EST 2005" 16232 972193 0 0 0 0 3 6 3
|
|
43 jdk1.6.0-b60 "Thu Nov 10 01:54:18 EST 2005" 16235 972346 0 0 0 0 3 6 3
|
|
</pre><p>
|
|
We could also generate that information directly, without creating an intermediate db.xml file, using the command
|
|
</p><pre class="screen">
|
|
computeBugHistory jdk1.6.0-b*/jre/lib/rt.xml | filterBugs -bugPattern IL_ db.xml | mineBugHistory -formatDates
|
|
</pre><p>We can then use that information to display a graph showing the number of infinite recursive loops
|
|
found by FindBugs in each build of Sun's JDK1.6.0. The blue area indicates the number of infinite
|
|
recursive loops in that build, the red area above it indicates the number of infinite recursive loops that existed
|
|
in some previous version but not in the current version (thus, the combined height of the red and blue areas
|
|
is guaranteed to never decrease, and goes up whenever a new infinite recursive loop bug is introduced). The height
|
|
of the red area is computed as the sum of the fixed, removed and dead values for each version.
|
|
The reductions in builds 13 and 14 came after Sun was notified about the bugs found by FindBugs in the JDK.
|
|
</p><div class="mediaobject"><img src="infiniteRecursiveLoops.png"></div><p>
|
|
Given the db.xml file that contains the results for all the jdk1.6.0 builds, the following command will show the history of high and medium priority correctness warnings:
|
|
</p><pre class="screen">
|
|
filterBugs -priority M -category C db.xml | mineBugHistory -formatDates
|
|
</pre><p>
|
|
generating the table:
|
|
</p><pre class="screen">
|
|
seq version time classes NCSS added newCode fixed removed retained dead active
|
|
0 jdk1.6.0-b12 "Thu Nov 11 09:07:20 EST 2004" 13128 811569 0 1075 0 0 0 0 1075
|
|
1 jdk1.6.0-b13 "Thu Nov 18 06:02:06 EST 2004" 13128 811570 0 0 0 0 1075 0 1075
|
|
2 jdk1.6.0-b14 "Thu Dec 02 06:12:26 EST 2004" 13145 811786 3 0 6 0 1069 0 1072
|
|
3 jdk1.6.0-b15 "Thu Dec 09 06:07:04 EST 2004" 13174 811693 2 1 3 0 1069 6 1072
|
|
4 jdk1.6.0-b16 "Thu Dec 16 06:21:28 EST 2004" 13175 811715 0 0 1 0 1071 9 1071
|
|
5 jdk1.6.0-b17 "Thu Dec 23 06:27:22 EST 2004" 13176 811974 0 0 1 0 1070 10 1070
|
|
6 jdk1.6.0-b19 "Thu Jan 13 06:41:16 EST 2005" 13176 812011 0 0 0 0 1070 11 1070
|
|
7 jdk1.6.0-b21 "Thu Jan 27 05:57:52 EST 2005" 13177 812173 0 0 1 0 1069 11 1069
|
|
8 jdk1.6.0-b23 "Thu Feb 10 05:44:36 EST 2005" 13179 812188 0 0 0 0 1069 12 1069
|
|
9 jdk1.6.0-b26 "Thu Mar 03 06:04:02 EST 2005" 13199 811770 0 0 2 1 1066 12 1066
|
|
10 jdk1.6.0-b27 "Thu Mar 10 04:48:38 EST 2005" 13189 812440 1 0 1 1 1064 15 1065
|
|
11 jdk1.6.0-b28 "Thu Mar 17 02:54:22 EST 2005" 13185 812056 0 0 0 0 1065 17 1065
|
|
12 jdk1.6.0-b29 "Thu Mar 24 03:09:20 EST 2005" 13117 809468 3 0 8 26 1031 17 1034
|
|
13 jdk1.6.0-b30 "Thu Mar 31 02:53:32 EST 2005" 13118 809501 0 0 0 0 1034 51 1034
|
|
14 jdk1.6.0-b31 "Thu Apr 07 03:00:14 EDT 2005" 13117 809572 0 0 0 0 1034 51 1034
|
|
15 jdk1.6.0-b32 "Thu Apr 14 02:56:56 EDT 2005" 13169 811096 1 1 0 1 1033 51 1035
|
|
16 jdk1.6.0-b33 "Thu Apr 21 02:46:22 EDT 2005" 13187 811942 3 0 2 1 1032 52 1035
|
|
17 jdk1.6.0-b34 "Thu Apr 28 02:49:00 EDT 2005" 13195 813488 0 1 0 0 1035 55 1036
|
|
18 jdk1.6.0-b35 "Thu May 05 02:49:04 EDT 2005" 13457 829837 0 36 2 0 1034 55 1070
|
|
19 jdk1.6.0-b36 "Thu May 12 02:59:46 EDT 2005" 13462 831278 0 0 0 0 1070 57 1070
|
|
20 jdk1.6.0-b37 "Thu May 19 02:55:08 EDT 2005" 13464 831971 0 1 1 0 1069 57 1070
|
|
21 jdk1.6.0-b38 "Thu May 26 03:08:16 EDT 2005" 13564 836565 1 7 2 6 1062 58 1070
|
|
22 jdk1.6.0-b39 "Fri Jun 03 03:10:48 EDT 2005" 13856 849992 6 39 5 0 1065 66 1110
|
|
23 jdk1.6.0-b40 "Thu Jun 09 03:30:28 EDT 2005" 15972 959619 7 147 11 0 1099 71 1253
|
|
24 jdk1.6.0-b41 "Thu Jun 16 03:19:22 EDT 2005" 15972 959619 0 0 0 0 1253 82 1253
|
|
25 jdk1.6.0-b42 "Fri Jun 24 03:38:54 EDT 2005" 15966 958581 3 0 1 2 1250 82 1253
|
|
26 jdk1.6.0-b43 "Thu Jul 14 03:09:34 EDT 2005" 16041 960544 5 11 15 8 1230 85 1246
|
|
27 jdk1.6.0-b44 "Thu Jul 21 03:05:54 EDT 2005" 16041 960547 0 0 0 0 1246 108 1246
|
|
28 jdk1.6.0-b45 "Thu Jul 28 03:26:10 EDT 2005" 16037 960606 19 0 2 0 1244 108 1263
|
|
29 jdk1.6.0-b46 "Thu Aug 04 03:02:48 EDT 2005" 15936 951355 13 1 1 32 1230 110 1244
|
|
30 jdk1.6.0-b47 "Thu Aug 11 03:18:56 EDT 2005" 15964 952387 163 8 7 20 1217 143 1388
|
|
31 jdk1.6.0-b48 "Thu Aug 18 08:10:40 EDT 2005" 15970 953421 0 0 0 0 1388 170 1388
|
|
32 jdk1.6.0-b49 "Thu Aug 25 03:24:38 EDT 2005" 16048 958940 1 11 1 0 1387 170 1399
|
|
33 jdk1.6.0-b50 "Thu Sep 01 01:52:40 EDT 2005" 16287 974937 19 27 16 7 1376 171 1422
|
|
34 jdk1.6.0-b51 "Thu Sep 08 01:55:36 EDT 2005" 16362 979377 1 15 3 0 1419 194 1435
|
|
35 jdk1.6.0-b52 "Thu Sep 15 02:04:08 EDT 2005" 16477 979399 0 0 1 1 1433 197 1433
|
|
36 jdk1.6.0-b53 "Thu Sep 22 02:00:28 EDT 2005" 16019 957900 13 12 16 20 1397 199 1422
|
|
37 jdk1.6.0-b54 "Thu Sep 29 01:54:34 EDT 2005" 16019 957900 0 0 0 0 1422 235 1422
|
|
38 jdk1.6.0-b55 "Thu Oct 06 01:54:14 EDT 2005" 16051 959014 1 4 7 0 1415 235 1420
|
|
39 jdk1.6.0-b56 "Thu Oct 13 01:54:12 EDT 2005" 16211 970835 6 8 37 0 1383 242 1397
|
|
40 jdk1.6.0-b57 "Thu Oct 20 01:55:26 EDT 2005" 16279 971627 0 0 0 0 1397 279 1397
|
|
41 jdk1.6.0-b58 "Thu Oct 27 01:56:30 EDT 2005" 16283 971945 0 1 1 0 1396 279 1397
|
|
42 jdk1.6.0-b59 "Thu Nov 03 01:56:58 EST 2005" 16232 972193 6 0 5 0 1392 280 1398
|
|
43 jdk1.6.0-b60 "Thu Nov 10 01:54:18 EST 2005" 16235 972346 0 0 0 0 1398 285 1398
|
|
44 jdk1.6.0-b61 "Thu Nov 17 01:58:42 EST 2005" 16202 971134 2 0 4 0 1394 285 1396
|
|
</pre></div><div class="sect2" title="2.2. Incremental history maintenance"><div class="titlepage"><div><div><h3 class="title"><a name="incrementalhistory"></a>2.2. Incremental history maintenance</h3></div></div></div><p>
|
|
If db.xml contains the results of running findbugs over builds b12 - b60, we can update db.xml to include the results of analyzing b61 with the commands:
|
|
</p><pre class="screen">
|
|
computeBugHistory -output db.xml db.xml jdk1.6.0-b61/jre/lib/rt.xml
|
|
</pre></div></div><div class="sect1" title="3. Ant example"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="antexample"></a>3. Ant example</h2></div></div></div><p>
|
|
Here is a complete ant script example for both running findbugs and running a chain of data-mining tools afterward:
|
|
</p><pre class="screen">
|
|
|
|
<project name="analyze_asm_util" default="findbugs">
|
|
<!-- findbugs task definition -->
|
|
<property name="findbugs.home" value="/Users/ben/Documents/workspace/findbugs/findbugs" />
|
|
<property name="jvmargs" value="-server -Xss1m -Xmx800m -Duser.language=en -Duser.region=EN -Dfindbugs.home=${findbugs.home}" />
|
|
|
|
<path id="findbugs.lib">
|
|
<fileset dir="${findbugs.home}/lib">
|
|
<include name="findbugs-ant.jar"/>
|
|
</fileset>
|
|
</path>
|
|
|
|
<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
|
|
<classpath refid="findbugs.lib" />
|
|
</taskdef>
|
|
|
|
<taskdef name="computeBugHistory" classname="edu.umd.cs.findbugs.anttask.ComputeBugHistoryTask">
|
|
<classpath refid="findbugs.lib" />
|
|
</taskdef>
|
|
|
|
<taskdef name="setBugDatabaseInfo" classname="edu.umd.cs.findbugs.anttask.SetBugDatabaseInfoTask">
|
|
<classpath refid="findbugs.lib" />
|
|
</taskdef>
|
|
|
|
<taskdef name="mineBugHistory" classname="edu.umd.cs.findbugs.anttask.MineBugHistoryTask">
|
|
<classpath refid="findbugs.lib" />
|
|
</taskdef>
|
|
|
|
<!-- findbugs task definition -->
|
|
<target name="findbugs">
|
|
<antcall target="analyze" />
|
|
<antcall target="mine" />
|
|
</target>
|
|
|
|
<!-- analyze task -->
|
|
<target name="analyze">
|
|
<!-- run findbugs against asm-util -->
|
|
<findbugs home="${findbugs.home}"
|
|
output="xml:withMessages"
|
|
timeout="90000000"
|
|
reportLevel="experimental"
|
|
workHard="true"
|
|
effort="max"
|
|
adjustExperimental="true"
|
|
jvmargs="${jvmargs}"
|
|
failOnError="true"
|
|
outputFile="out.xml"
|
|
projectName="Findbugs"
|
|
debug="false">
|
|
<class location="asm-util-3.0.jar" />
|
|
</findbugs>
|
|
</target>
|
|
|
|
<target name="mine">
|
|
|
|
<!-- Set info to the latest analysis -->
|
|
<setBugDatabaseInfo home="${findbugs.home}"
|
|
withMessages="true"
|
|
name="asm-util-3.0.jar"
|
|
input="out.xml"
|
|
output="out-rel.xml"/>
|
|
|
|
<!-- Checking if history file already exists (out-hist.xml) -->
|
|
<condition property="mining.historyfile.available">
|
|
<available file="out-hist.xml"/>
|
|
</condition>
|
|
<condition property="mining.historyfile.notavailable">
|
|
<not>
|
|
<available file="out-hist.xml"/>
|
|
</not>
|
|
</condition>
|
|
|
|
<!-- this target is executed if the history file do not exist (first run) -->
|
|
<antcall target="history-init">
|
|
<param name="data.file" value="out-rel.xml" />
|
|
<param name="hist.file" value="out-hist.xml" />
|
|
</antcall>
|
|
<!-- else this one is executed -->
|
|
<antcall target="history">
|
|
<param name="data.file" value="out-rel.xml" />
|
|
<param name="hist.file" value="out-hist.xml" />
|
|
<param name="hist.summary.file" value="out-hist.txt" />
|
|
</antcall>
|
|
</target>
|
|
|
|
<!-- Initializing history file -->
|
|
<target name="history-init" if="mining.historyfile.notavailable">
|
|
<copy file="${data.file}" tofile="${hist.file}" />
|
|
</target>
|
|
|
|
<!-- Computing bug history -->
|
|
<target name="history" if="mining.historyfile.available">
|
|
<!-- Merging ${data.file} into ${hist.file} -->
|
|
<computeBugHistory home="${findbugs.home}"
|
|
withMessages="true"
|
|
output="${hist.file}">
|
|
<dataFile name="${hist.file}"/>
|
|
<dataFile name="${data.file}"/>
|
|
</computeBugHistory>
|
|
|
|
<!-- Compute history into ${hist.summary.file} -->
|
|
<mineBugHistory home="${findbugs.home}"
|
|
formatDates="true"
|
|
noTabs="true"
|
|
input="${hist.file}"
|
|
output="${hist.summary.file}"/>
|
|
</target>
|
|
|
|
</project>
|
|
|
|
</pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rejarForAnalysis.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="license.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 11. Using rejarForAnalysis </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 13. License</td></tr></table></div></body></html> |