<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Chapter 11. Data mining of bugs with FindBugs™</title><meta name="generator" content="DocBook XSL Stylesheets V1.71.1"><link rel="start" href="index.html" title="FindBugs™ Manual"><link rel="up" href="index.html" title="FindBugs™ Manual"><link rel="prev" href="annotations.html" title="Chapter 10. Annotations"><link rel="next" href="license.html" title="Chapter 12. 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 11. Data mining of bugs with <span class="application">FindBugs</span>™</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="annotations.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" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="datamining"></a>Chapter 11. 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#antexemple">3. Ant exemple</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><strong class="command">setBugDatabaseInfo</strong></span> (<a 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><strong class="command">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><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="commands"></a>1. Commands</h2></div></div></div><p> The current tools for FindBugs data mining are designed to be invoked from the command line.</p><p> Briefly, the commands are:</p><div class="variablelist"><dl><dt><span class="term"><span><strong class="command"><a 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><strong class="command"><a 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><strong class="command"><a 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><strong class="command"><a 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><strong class="command"><a 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><strong class="command"><a 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><strong class="command"><a 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><strong class="command"><a 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" lang="en"><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><strong class="command">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" lang="en"><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>The options are:</p><div class="variablelist"><dl><dt><span class="term"><code class="option">-output</code> <em class="replaceable"><code>filename</code></em></span></dt><dd><p> specify that the output should be saved in the file <em class="replaceable"><code>filename</code></em> </p><p> The output file is not written until all input files are read, so you may overwrite one of the input files if you wish. </p></dd><dt><span class="term"><code class="option">-overrideRevisionNames</code></span></dt><dd><p> override revision names for each version with names computed from the filenames </p></dd><dt><span class="term"><code class="option">-noPackageMoves</code></span></dt><dd><p> if a class seems to have moved from one package to another, treat warnings in that class as two seperate warnings </p></dd><dt><span class="term"><code class="option">-preciseMatch</code></span></dt><dd><p> require bug patterns to match precisely </p></dd><dt><span class="term"><code class="option">-precisePriorityMatch</code></span></dt><dd><p> only consider two warnings to be the same if their priorities match exactly </p></dd><dt><span class="term"><code class="option">-quiet</code></span></dt><dd><p> don't generate any outout to standard out unless there is an error </p></dd></dl></div></div><div class="sect2" lang="en"><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><div class="table"><a name="filterOptionsTable"></a><p class="title"><b>Table 11.1. Options for filterBugs command</b></p><div class="table-contents"><table summary="Options for filterBugs command" border="1"><colgroup><col><col></colgroup><thead><tr><th align="left">Option</th><th align="left">Meaning</th></tr></thead><tbody><tr><td align="left">-not</td><td align="left">reverse (all) switches for the filter</td></tr><tr><td align="left">-withSource[:truth]</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 bugs matching given filter</td></tr><tr><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">allow only warnings containing this text in a manual annotation</td></tr><tr><td align="left">-classified[:truth]</td><td align="left">allow only classified warnings</td></tr><tr><td align="left">-serious[:truth]</td><td align="left">allow only warnings manually classified as serious</td></tr><tr><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">allow only warnings that first occurred before this version</td></tr><tr><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">allow only warnings that last occurred in this version</td></tr><tr><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">allow only warnings present in this version</td></tr><tr><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">allow only warnings alive in the last sequence number</td></tr><tr><td align="left">-introducedByChange[:truth]</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">allow only warnings removed by a change of a persisting class</td></tr><tr><td align="left">-newCode[:truth]</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">allow only warnings removed by removal of a class</td></tr><tr><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">allow only bugs whose primary class name matches this pattern</td></tr><tr><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">allow only warnings with a category that starts with this string</td></tr><tr><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">the generated XML should contain textual messages</td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" lang="en"><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>The options are:</p><div class="variablelist"><dl><dt><span class="term"><code class="option">-formatDates</code></span></dt><dd><p> render dates in textual form </p></dd><dt><span class="term"><code class="option">-noTabs</code></span></dt><dd><p> delimit columns with groups of spaces instead of tabs. This can be easier to read from a shell with a fixed-width font. </p><p> 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></dd><dt><span class="term"><code class="option">-summary</code></span></dt><dd><p> Output will be only a terse summary of changes over the last ten entries. (The output format is subject to change.) </p></dd></dl></div><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 11.2. 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" lang="en"><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. In 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 11.3. 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" lang="en"><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>The options are:</p><div class="variablelist"><dl><dt><span class="term"><code class="option">-longBugCodes</code></span></dt><dd><p> use the full bug pattern code instead of the two-letter abbreviation </p></dd><dt><span class="term"><code class="option">-html</code><em class="replaceable"><code>[:stylesheet]</code></em></span></dt><dd><p> Generate html output with the specified stylesheet, or default.xsl if no stylesheet is specified. </p><p> You may specify plain.xsl, default.xsl, fancy.xsl, fancy-hist.xsl, or your own XSL stylesheet. Despite the name of this option, you may specify a stylesheet that emits something other than html. </p></dd></dl></div></div><div class="sect2" lang="en"><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><div class="table"><a name="setBugDatabaseInfoOptions"></a><p class="title"><b>Table 11.4. setBugDatabaseInfo Options</b></p><div class="table-contents"><table summary="setBugDatabaseInfo Options" border="1"><colgroup><col><col></colgroup><thead><tr><th align="left">Option</th><th align="left">Meaning</th></tr></thead><tbody><tr><td align="left">-name <em class="replaceable"><code>name</code></em></td><td align="left">set name for (last) revision</td></tr><tr><td align="left">-timestamp <em class="replaceable"><code>when</code></em></td><td align="left">set timestamp for (last) revision</td></tr><tr><td align="left">-source <em class="replaceable"><code>directory</code></em></td><td align="left">add specified directory to the source search path</td></tr><tr><td align="left">-findSource <em class="replaceable"><code>directory</code></em></td><td align="left">find and add all relevant source directions contained within specified directory</td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" lang="en"><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 11.5. 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" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="examples"></a>2. Examples</h2></div></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="unixscriptsexemples"></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" lang="en"><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" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="antexemple"></a>3. Ant exemple</h2></div></div></div><p> Here is a complete ant script exemple for both running findbugs and generating an HTML report of bugs history using fancy-hist.xsl. </p><pre class="screen"> <?xml version="1.0" encoding="UTF-8"?> <project basedir="." default="findbugs" name="findbugs"> <property name="findbugs.home" value="d:/dev/findbugs" /> <property name="jvmargs" value="-server -Xss1m -Xmx800m -Duser.language=en -Duser.region=EN -Dfindbugs.home=${findbugs.home}" /> <!-- findbugs task definition --> <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> <!-- run findbugs against --> <target name="findbugs"> <!-- use current date & time as release name --> <tstamp> <format property="release" pattern="yyyy-MM-dd_HH.mm.ss"/> </tstamp> <mkdir dir="temp" /> <antcall target="analyze" /> <antcall target="mine" /> </target> <!-- analyze task --> <target name="analyze"> <!-- run findbugs against itself --> <findbugs home="${findbugs.home}" output="xml:withMessages" timeout="90000000" reportLevel="experimental" workHard="true" effort="max" adjustExperimental="true" jvmargs="${jvmargs}" failOnError="true" outputFile="temp/findbugs-${release}.xml" projectName="Findbugs" debug="false" > <class location="${findbugs.home}/lib/findbugs-ant.jar" /> <class location="${findbugs.home}/lib/findbugs.jar" /> <class location="${findbugs.home}/lib/findbugsGUI.jar" /> <class location="${findbugs.home}/plugin/coreplugin.jar" /> <auxClasspath> <fileset file="${findbugs.home}/lib/AppleJavaExtensions.jar"/> <fileset file="${findbugs.home}/lib/bcel.jar"/> <fileset file="${findbugs.home}/lib/dom4j-full.jar"/> <fileset file="${findbugs.home}/lib/junit.jar"/> <fileset file="${ant.home}/lib/ant.jar"/> </auxClasspath> </findbugs> <!-- generate a non historized report --> <xslt destdir="." in="temp/findbugs-${release}.xml" out="findbugs-${release}.html" style="./fancy.xsl" /> </target> <target name="mine"> <!-- Set release info to the latest analysis --> <java classname="edu.umd.cs.findbugs.workflow.SetBugDatabaseInfo" fork="true"> <jvmarg line="${jvmargs}"/> <arg line="-withMessages -name ${release} temp/findbugs-${release}.xml temp/findbugs-${release}-rel.xml"/> <classpath> <pathelement path="${findbugs.home}/lib/findbugs.jar"/> </classpath> </java> <!-- Checking if history file already exists (findbugs-hist.xml) --> <condition property="mining.historyfile.available"> <available file="findbugs-hist.xml"/> </condition> <condition property="mining.historyfile.notavailable"> <not> <available file="findbugs-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="temp/findbugs-${release}-rel.xml" /> <param name="hist.file" value="findbugs-hist.xml" /> </antcall> <!-- else this one is executed --> <antcall target="history"> <param name="data.file" value="temp/findbugs-${release}-rel.xml" /> <param name="hist.file" value="findbugs-hist.xml" /> <param name="hist.summary.file" value="findbugs-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} --> <java classname="edu.umd.cs.findbugs.workflow.Update" fork="true"> <jvmarg line="${jvmargs}"/> <arg line="-withMessages -output ${hist.file} ${hist.file} ${data.file}"/> <classpath> <pathelement path="${findbugs.home}/lib/findbugs.jar"/> </classpath> </java> <!-- Compute history into ${hist.summary.file} --> <java classname="edu.umd.cs.findbugs.workflow.MineBugHistory" fork="true"> <jvmarg line="${jvmargs}"/> <arg line="-formatDates -noTabs ${hist.file} ${hist.summary.file}"/> <classpath> <pathelement path="${findbugs.home}/lib/findbugs.jar"/> </classpath> </java> <!-- Generate HTML report --> <xslt destdir="." in="${hist.file}" out="${hist.file}.html" > <style> <zipentry zipfile='d:/dev/findbugs/lib/findbugs.jar' name='fancy-hist.xsl' /> </style> </xslt> </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="annotations.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 10. Annotations </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 12. License</td></tr></table></div></body></html>