FindBugs Plugin – passo a passo Chapter 1. Introduction Table of Contents 1. Requirements FindBugs™ is a program to find bugs in Java programs. It looks for instances of "bug patterns" --- code instances that are likely to be errors. This document describes version 1.3.9 of FindBugs.We are very interested in getting your feedback on FindBugs. Please visit the FindBugs web page for the latest information on FindBugs, contact information, and support resources such as information about the FindBugs mailing lists. 1. Requirements To use FindBugs, you need a runtime environment compatible with Java 2 Standard Edition, version 1.5 or later. FindBugs is platform independent, and is known to run on GNU/Linux, Windows, and MacOS X platforms. You should have at least 512 MB of memory to use FindBugs. To analyze very large projects, more memory may be needed. Chapter 2. Installing FindBugs™ Table of Contents 1. Extracting the Distribution This chapter explains how to install FindBugs. 1. Extracting the Distribution The easiest way to install FindBugs is to download a binary distribution. Binary distributions are available in gzipped tar format and zip format. Once you have downloaded a binary distribution, extract it into a directory of your choice. Extracting a gzipped tar format distribution: $ gunzip -c findbugs-1.3.9.tar.gz | tar xvf - Extracting a zip format distribution: C:\Software>unzip findbugs-1.3.9.zip Usually, extracting a binary distribution will create a directory ending in findbugs-1.3.9. For example, if you extracted the binary distribution from the C:\Software directory, then the FindBugs software will be extracted into the directory C:\Software\findbugs-1.3.9. This directory is the FindBugs home directory. We'll refer to it as $FINDBUGS_HOME (or %FINDBUGS_HOME% for Windows) throughout this manual. Chapter 3. Building FindBugs™ from Source Table of Contents 1. Prerequisites 2. Extracting the Source Distribution 3. Modifying local.properties 4. Running Ant 5. Running FindBugs™ from a source directory This chapter describes how to build FindBugs from source code. Unless you are interesting in modifying FindBugs, you will probably want to skip to the next chapter. 1. Prerequisites To compile FindBugs from source, you will need the following: The FindBugs source distribution JDK 1.5.0 beta or later Apache Ant, version 1.6.3 or later Warning The version of Ant included as /usr/bin/ant on Redhat Linux systems will not work for compiling FindBugs. We recommend you install a binary distribution of Ant downloaded from the Ant website. Make sure that when you run Ant your JAVA_HOME environment variable points to the directory in which you installed JDK 1.5 (or later). If you want to be able to generate formatted versions of the FindBugs documentation, you will also need the following software: The DocBook XSL Stylesheets. These are required to convert the FindBugs manual into HTML format. The Saxon XSLT Processor. (Also required for converting the FindBugs manual to HTML.) 2. Extracting the Source Distribution After you download the source distribution, you'll need to extract it into a working directory. A typical command to do this is: $ unzip findbugs-1.3.9-source.zip 3. Modifying local.properties If you intend to build the FindBugs documentation, you will need to modify the local.properties file used by the Ant build.xml file to build FindBugs. If you do not want to build the FindBugs documentation, then you can ignore this file. The local.properties overrides definitions in the build.properties file. The build.properties file looks something like this: # User Configuration: # This section must be modified to reflect your system. local.software.home =/export/home/daveho/linux # Set this to the directory containing the DocBook Modular XSL Stylesheets # from http://docbook.sourceforge.net/projects/xsl/ xsl.stylesheet.home =${local.software.home}/docbook/docbook-xsl-1.71.1 # Set this to the directory where Saxon (http://saxon.sourceforge.net/) # is installed. saxon.home =${local.software.home}/java/saxon-6.5.5 The xsl.stylesheet.home property specifies the full path to the directory where you have installed the DocBook Modular XSL Stylesheets. You only need to specify this property if you will be generating the FindBugs documentation. The saxon.home property is the full path to the directory where you installed the Saxon XSLT Processor. You only need to specify this property if you will be generating the FindBugs documentation. 4. Running Ant Once you have extracted the source distribution, made sure that Ant is installed, modified build.properties (optional), and configured the tools (such as Saxon), you are ready to build FindBugs. Invoking Ant is a simple matter of running the command $ ant target where target is one of the following: build This target compiles the code for FindBugs. It is the default target. docs This target formats the documentation. (It also compiles some of the source code as a side-effect.) runjunit This target compiles and runs the internal JUnit tests included in FindBugs. It will print an error message if any unit tests fail. bindist Builds a binary distribution of FindBugs. The target creates both .zip and .tar.gz archives. After running an Ant command, you should see output similar to the following (after some other messages regarding the tasks that Ant is running): BUILD SUCCESSFUL Total time: 17 seconds 5. Running FindBugs™ from a source directory The Ant build script for FindBugs is written such that after building the build target, the working directory is set up just like a binary distribution. So, the information about running FindBugs in Chapter 4, Running FindBugs™ applies to source distributions, too. Chapter 4. Running FindBugs™ Table of Contents 1. Quick Start 2. Executing FindBugs 3. Command-line Options FindBugs has two user interfaces: a graphical user interface (GUI) and a command line user interface. This chapter describes how to run each of these user interfaces. Warning This chapter is in the process of being re-written. The rewrite is not complete yet. 1. Quick Start If you are running FindBugs on a Windows system, double-click on the file %FINDBUGS_HOME%\lib\findbugs.jar to start the FindBugs GUI. On a Unix, Linux, or Mac OS X system, run the $FINDBUGS_HOME/bin/findbugs script, or run the command java -jar $FINDBUGS_HOME/lib/findbugs.jar to run the FindBugs GUI. Refer to Chapter 5, Using the FindBugs GUI for information on how to use the GUI. 2. Executing FindBugs This section describes how to invoke the FindBugs program. There are two ways to invoke FindBugs: directly, or using a wrapper script. 2.1. Direct invocation of FindBugs The preferred method of running FindBugs is to directly execute $FINDBUGS_HOME/lib/findbugs.jar using the -jar command line switch of the JVM (java) executable. (Versions of FindBugs prior to 1.3.5 required a wrapper script to invoke FindBugs.) The general syntax of invoking FindBugs directly is the following: java [JVM arguments] -jar $FINDBUGS_HOME/lib/findbugs.jar options... 2.1.1. Choosing the User Interface The first command line option chooses the FindBugs user interface to execute. Possible values are: -gui: runs the graphical user interface (GUI) -textui: runs the command line user interface -version: displays the FindBugs version number -help: displays help information for the FindBugs command line user interface -gui1: executes the original (obsolete) FindBugs graphical user interface 2.1.2. Java Virtual Machine (JVM) arguments Several Java Virtual Machine arguments are useful when invoking FindBugs. -XmxNNm Set the maximum Java heap size to NN megabytes. FindBugs generally requires a large amount of memory. For a very large project, using 1500 megabytes is not unusual. -Dname=value Set a Java system property. For example, you might use the argument -Duser.language=ja to display GUI messages in Japanese. 2.2. Invocation of FindBugs using a wrapper script Another way to run FindBugs is to use a wrapper script. On Unix-like systems, use the following command to invoke the wrapper script: $ $FINDBUGS_HOME/bin/findbugs options... On Windows systems, the command to invoke the wrapper script is C:\My Directory>%FINDBUGS_HOME%\bin\findbugs.bat options... On both Unix-like and Windows systems, you can simply add the $FINDBUGS_HOME/bin directory to your PATH environment variable and then invoke FindBugs using the findbugs command. 2.2.1. Wrapper script command line options The FindBugs wrapper scripts support the following command-line options. Note that these command line options are not handled by the FindBugs program per se; rather, they are handled by the wrapper script. -jvmArgs args Specifies arguments to pass to the JVM. For example, you might want to set a JVM property: $ findbugs -textui -jvmArgs "-Duser.language=ja" myApp.jar -javahome directory Specifies the directory containing the JRE (Java Runtime Environment) to use to execute FindBugs. -maxHeap size Specifies the maximum Java heap size in megabytes. The default is 256. More memory may be required to analyze very large programs or libraries. -debug Prints a trace of detectors run and classes analyzed to standard output. Useful for troubleshooting unexpected analysis failures. -property name=value This option sets a system property. FindBugs uses system properties to configure analysis options. See Chapter 9, Analysis Properties. You can use this option multiple times in order to set multiple properties. Note: In most versions of Windows, the name=value string must be in quotes. 3. Command-line Options This section describes the command line options supported by FindBugs. These command line options may be used when invoking FindBugs directly, or when using a wrapper script. 3.1. Common command-line options These options may be used with both the GUI and command-line interfaces. -effort:min This option disables analyses that increase precision but also increase memory consumption. You may want to try this option if you find that FindBugs runs out of memory, or takes an unusually long time to complete its analysis. -effort:max Enable analyses which increase precision and find more bugs, but which may require more memory and take more time to complete. -project project Specify a project to be analyzed. The project file you specify should be one that was created using the GUI interface. It will typically end in the extension .fb or .fbp. 3.2. GUI Options These options are only accepted by the Graphical User Interface. -look:plastic|gtk|native Set Swing look and feel. 3.3. Text UI Options These options are only accepted by the Text User Interface. -sortByClass Sort reported bug instances by class name. -include filterFile.xml Only report bug instances that match the filter specified by filterFile.xml. See Chapter 8, Filter Files. -exclude filterFile.xml Report all bug instances except those matching the filter specified by filterFile.xml. See Chapter 8, Filter Files. -onlyAnalyze com.foobar.MyClass,com.foobar.mypkg.* Restrict analysis to find bugs to given comma-separated list of classes and packages. Unlike filtering, this option avoids running analysis on classes and packages that are not explicitly matched: for large projects, this may greatly reduce the amount of time needed to run the analysis. (However, some detectors may produce inaccurate results if they aren't run on the entire application.) Classes should be specified using their full classnames (including package), and packages should be specified in the same way they would in a Java import statement to import all classes in the package (i.e., add .* to the full name of the package). Replace .* with .- to also analyze all subpackages. -low Report all bugs. -medium Report medium and high priority bugs. This is the default setting. -high Report only high priority bugs. -relaxed Relaxed reporting mode. For many detectors, this option suppresses the heuristics used to avoid reporting false positives. -xml Produce the bug reports as XML. The XML data produced may be viewed in the GUI at a later time. You may also specify this option as -xml:withMessages; when this variant of the option is used, the XML output will contain human-readable messages describing the warnings contained in the file. XML files generated this way are easy to transform into reports. -html Generate HTML output. By default, FindBugs will use the default.xsl XSLT stylesheet to generate the HTML: you can find this file in findbugs.jar, or in the FindBugs source or binary distributions. Variants of this option include -html:plain.xsl, -html:fancy.xsl and -html:fancyhist.xsl. The plain.xsl stylesheet does not use Javascript or DOM, and may work better with older web browsers, or for printing. The fancy.xsl stylesheet uses DOM and Javascript for navigation and CSS for visual presentation. The fancy-hist.xsl an evolution of fancy.xsl stylesheet. It makes an extensive use of DOM and Javascript for dynamically filtering the lists of bugs. If you want to specify your own XSLT stylesheet to perform the transformation to HTML, specify the option as -html:myStylesheet.xsl, where myStylesheet.xsl is the filename of the stylesheet you want to use. -emacs Produce the bug reports in Emacs format. -xdocs Produce the bug reports in xdoc XML format for use with Apache Maven. -output filename Produce the output in the specified file. -outputFile filename This argument is deprecated. Use -output instead. -nested[:true|false] This option enables or disables scanning of nested jar and zip files found in the list of files and directories to be analyzed. By default, scanning of nested jar/zip files is enabled. To disable it, add nested:false to the command line arguments. -auxclasspath classpath Set the auxiliary classpath for analysis. This classpath should include all jar files and directories containing classes that are part of the program being analyzed but you do not want to have analyzed for bugs. Chapter 5. Using the FindBugs GUI Table of Contents 1. Creating a Project 2. Running the Analysis 3. Browsing Results 4. Saving and Opening This chapter describes how to use the FindBugs graphical user interface (GUI). 1. Creating a Project After you have started FindBugs using the findbugs command, choose the File → New Project menu item. You will see a dialog which looks like this: Use the "Add" button next to the "Class archives and directories to analyze" text field to select a Java archive file (zip, jar, ear, or war file) or directory containing java classes to analyze for bugs. You may add multiple archives/directories. You can also add the source directories which contain the source code for the Java archives you are analyzing. This will enable FindBugs to highlight the source code which contains a possible error. The source directories you add should be the roots of the Java package hierarchy. For example, if your application is contained in the org.foobar.myapp package, you should add the parent directory of the org directory to the source directory list for the project. Another optional step is to add additional Jar files or directories as "Auxiliary classpath locations" entries. You should do this if the archives and directories you are analyzing have references to other classes which are not included in the analyzed archives/directories and are not in the standard runtime classpath. Some of the bug pattern detectors in FindBugs make use of class hierarchy information, so you will get more accurate results if the entire class hierarchy is available which FindBugs performs its analysis. 2. Running the Analysis Once you have added all of the archives, directories, and source directories, click the "Finish" button to analyze the classes contained in the Jar files. Note that for a very large program on an older computer, this may take quite a while (tens of minutes). A recent computer with ample memory will typically be able to analyze a large program in only a few minutes. 3. Browsing Results When the analysis completes, you will see a screen like the following: The upper left-hand pane of the window shows the bug tree; this is a hierarchical representation of all of the potential bugs detected in the analyzed Jar files. When you select a particular bug instance in the top pane, you will see a description of the bug in the "Details" tab of the bottom pane. In addition, the source code pane on the upper-right will show the program source code where the potential bug occurs, if source is available. In the above example, the bug is a stream object that is not closed. The source code window highlights the line where the stream object is created. You may add a textual annotations to bug instances. To do so, type them into the text box just below the hierarchical view. You can type any information which you would like to record. When you load and save bug results files, the annotations are preserved. 4. Saving and Opening You may use the File → Save as... menu option to save your work. To save your work, including the jar file lists you specified and all bug results, choose "FindBugs analysis results (.xml)" from the drop-down list in the "Save as..." dialog. There are also options for saving just the jar file lists ("FindBugs project file (.fbp)") or just the results ("FindBugs analysis file (.fba)"). A saved file may be loaded with the File → Open... menu option. Chapter 6. Using the FindBugs™ Ant task Table of Contents 1. Installing the Ant task 2. Modifying build.xml 3. Executing the task 4. Parameters This chapter describes how to integrate FindBugs into a build script for Ant, which is a popular Java build and deployment tool. Using the FindBugs Ant task, your build script can automatically run FindBugs on your Java code. The Ant task was generously contributed by Mike Fagan. 1. Installing the Ant task To install the Ant task, simply copy $FINDBUGS_HOME/lib/findbugs-ant.jar into the lib subdirectory of your Ant installation. Note It is strongly recommended that you use the Ant task with the version of FindBugs it was included with. We do not guarantee that the Ant task Jar file will work with any version of FindBugs other than the one it was included with. 2. Modifying build.xml To incorporate FindBugs into build.xml (the build script for Ant), you first need to add a task definition. This should appear as follows: <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"/> The task definition specifies that when a findbugs element is seen in build.xml, it should use the indicated class to execute the task. After you have added the task definition, you can define a target which uses the findbugs task. Here is an example which could be added to the build.xml for the Apache BCEL library. <property name="findbugs.home" value="/export/home/daveho/work/findbugs" /> <target name="findbugs" depends="jar"> <findbugs home="${findbugs.home}" output="xml" outputFile="bcel-fb.xml" > <auxClasspath path="${basedir}/lib/Regex.jar" /> <sourcePath path="${basedir}/src/java" /> <class location="${basedir}/bin/bcel.jar" /> </findbugs> </target> The findbugs element must have the home attribute set to the directory in which FindBugs is installed; in other words, $FINDBUGS_HOME. See Chapter 2, Installing FindBugs™. This target will execute FindBugs on bcel.jar, which is the Jar file produced by BCEL's build script. (By making it depend on the "jar" target, we ensure that the library is fully compiled before running FindBugs on it.) The output of FindBugs will be saved in XML format to a file called bcel-fb.xml. An auxiliary Jar file, Regex.jar, is added to the aux classpath, because it is referenced by the main BCEL library. A source path is specified so that the saved bug data will have accurate references to the BCEL source code. 3. Executing the task Here is an example of invoking Ant from the command line, using the findbugs target defined above. [daveho@noir]$ ant findbugs Buildfile: build.xml init: compile: examples: jar: findbugs: [findbugs] Running FindBugs... [findbugs] Bugs were found [findbugs] Output saved to bcel-fb.xml BUILD SUCCESSFUL Total time: 35 seconds In this case, because we saved the bug results in an XML file, we can use the FindBugs GUI to view the results; see Chapter 4, Running FindBugs™. 4. Parameters This section describes the parameters that may be specified when using the FindBugs task. class A nested element specifying which classes to analyze. The class element must specify a location attribute which names the archive file (jar, zip, etc.), directory, or class file to be analyzed. Multiple class elements may be specified as children of a single findbugs element. auxClasspath An optional nested element which specifies a classpath (Jar files or directories) containing classes used by the analyzed library or application, but which you don't want to analyze. It is specified the same way as Ant's classpath element for the Java task. sourcePath An optional nested element which specifies a source directory path containing source files used to compile the Java code being analyzed. By specifying a source path, any generated XML bug output will have complete source information, which allows later viewing in the GUI. home A required attribute. It must be set to the name of the directory where FindBugs is installed. quietErrors An optional boolean attribute. If true, reports of serious analysis errors and missing classes will be suppressed in the FindBugs output. Default is false. reportLevel An optional attribute. It specifies the priority threshold for reporting bugs. If set to "low", all bugs are reported. If set to "medium" (the default), medium and high priority bugs are reported. If set to "high", only high priority bugs are reported. output Optional attribute. It specifies the output format. If set to "xml" (the default), output is in XML format. If set to "xml:withMessages", output is in XML format augmented with human-readable messages. (You should use this format if you plan to generate a report using an XSL stylesheet.) If set to "html", output is in HTML formatted (default stylesheet is default.xsl). If set to "text", output is in ad-hoc text format. If set to "emacs", output is in Emacs error message format. If set to "xdocs", output is xdoc XML for use with Apache Maven. stylesheet Optional attribute. It specifies the stylesheet to use to generate html output when the output is set to html. Stylesheets included in the FindBugs distribution include default.xsl, fancy.xsl, fancy-hist.xsl, plain.xsl, and summary.xsl. The default value, if no stylesheet attribute is provided, is default.xsl. sort Optional attribute. If the output attribute is set to "text", then the sort attribute specifies whether or not reported bugs are sorted by class. Default is true. outputFile Optional attribute. If specified, names the output file in which the FindBugs output will be saved. By default, the output is displayed directly by Ant. debug Optional boolean attribute. If set to true, FindBugs prints diagnostic information about which classes are being analyzed, and which bug pattern detectors are being run. Default is false. effort Set the analysis effort level. The value specified should be one of min, default, or max. See Section 3, “Command-line Options” for more information about setting the analysis level. conserveSpace Synonym for effort="min". workHard Synonym for effort="max". visitors Optional attribute. It specifies a comma-separated list of bug detectors which should be run. The bug detectors are specified by their class names, without any package qualification. By default, all detectors which are not disabled by default are run. omitVisitors Optional attribute. It is like the visitors attribute, except it specifies detectors which will not be run. excludeFilter Optional attribute. It specifies the filename of a filter specifying bugs to exclude from being reported. See Chapter 8, Filter Files. includeFilter Optional attribute. It specifies the filename of a filter specifying which bugs are reported. See Chapter 8, Filter Files. projectFile Optional attribute. It specifies the name of a project file. Project files are created by the FindBugs GUI, and specify classes, aux classpath entries, and source directories. By naming a project, you don't need to specify any class elements, nor do you need to specify auxClasspath or sourcePath attributes. See Chapter 4, Running FindBugs™ for how to create a project. jvmargs Optional attribute. It specifies any arguments that should be passed to the Java virtual machine used to run FindBugs. You may need to use this attribute to specify flags to increase the amount of memory the JVM may use if you are analyzing a very large program. systemProperty Optional nested element. If specified, defines a system property. The name attribute specifies the name of the system property, and the value attribute specifies the value of the system property. timeout Optional attribute. It specifies the amount of time, in milliseconds, that the Java process executing FindBugs may run before it is assumed to be hung and is terminated. The default is 600,000 milliseconds, which is ten minutes. Note that for very large programs, FindBugs may require more than ten minutes to complete its analysis. failOnError Optional boolean attribute. Whether to abort the build process if there is an error running FindBugs. Defaults to "false" errorProperty Optional attribute which specifies the name of a property that will be set to "true" if an error occurs while running FindBugs. warningsProperty Optional attribute which specifies the name of a property that will be set to "true" if any warnings are reported by FindBugs on the analyzed program. Chapter 7. Using the FindBugs™ Eclipse plugin Table of Contents 1. Requirements 2. Installation 3. Using the Plugin 4. Troubleshooting The FindBugs Eclipse plugin allows FindBugs to be used within the Eclipse IDE. The FindBugs Eclipse plugin was generously contributed by Peter Friese. Phil Crosby and Andrei Loskutov contributed major improvements to the plugin. 1. Requirements To use the FindBugs Plugin for Eclipse, you need Eclipse 3.3 or later, and JRE/JDK 1.5 or later. 2. Installation We provide update sites that allow you to automatically install FindBugs into Eclipse and also query and install updates. There are three different update sites FindBugs Eclipse update sites http://findbugs.cs.umd.edu/eclipse/ Only provides official releases of FindBugs. http://findbugs.cs.umd.edu/eclips-candidate/ Provides official releases and release candidates of FindBugs. http://findbugs.cs.umd.edu/eclipse-daily/ Provides the daily build of FindBugs. No testing other than that it compiles. You can also manually download the plugin from the following link: http://prdownloads.sourceforge.net/findbugs/edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821.zip?downl oad. Extract it in Eclipse's "plugins" subdirectory. (So <eclipse_install_dir>/plugins/edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821/findbugs.png should be the path to the FindBugs logo.) Once the plugin is extracted, start Eclipse and choose Help → About Eclipse Platform → Plug-in Details. You should find a plugin called "FindBugs Plug-in" provided by "FindBugs Project". 3. Using the Plugin To get started, right click on a Java project in Package Explorer, and select the option labeled "Find Bugs". FindBugs will run, and problem markers (displayed in source windows, and also in the Eclipse Problems view) will point to locations in your code which have been identified as potential instances of bug patterns. You can also run FindBugs on existing java archives (jar, ear, zip, war etc). Simply create an empty Java project and attach archives to the project classpath. Having that, you can now right click the archive node in Package Explorer and select the option labeled "Find Bugs". If you additionally configure the source code locations for the binaries, FindBugs will also link the generated warnings to the right source files. You may customize how FindBugs runs by opening the Properties dialog for a Java project, and choosing the "Findbugs" property page. Options you may choose include: Enable or disable the "Run FindBugs Automatically" checkbox. When enabled, FindBugs will run every time you modify a Java class within the project. Choose minimum warning priority and enabled bug categories. These options will choose which warnings are shown. For example, if you select the "Medium" warning priority, only Medium and High priority warnings will be shown. Similarly, if you uncheck the "Style" checkbox, no warnings in the Style category will be displayed. Select detectors. The table allows you to select which detectors you want to enable for your project. 4. Troubleshooting The FindBugs Eclipse plugin is still experimental. This section lists common problems with the plugin and (if known) how to resolve them. If you do not see any FindBugs problem markers (in your source windows or in the Problems View), you may need to change your Problems View filter settings. See http://findbugs.sourceforge.net/FAQ.html#q7 for more information. Chapter 8. Filter Files Table of Contents 1. Introduction to Filter Files 2. Types of Match clauses 3. Java element name matching 4. Caveats 5. Examples 6. Complete Example Filter files may be used to include or exclude bug reports for particular classes and methods. This chapter explains how to use filter files. Planned Features Filters are currently only supported by the Command Line interface. Eventually, filter support will be added to the GUI. 1. Introduction to Filter Files Conceptually, a filter matches bug instances against a set of criteria. By defining a filter, you can select bug instances for special treatment; for example, to exclude or include them in a report. A filter file is an XML document with a top-level FindBugsFilter element which has some number of Match elements as children. Each Match element represents a predicate which is applied to generated bug instances. Usually, a filter will be used to exclude bug instances. For example: $ findbugs -textui -exclude myExcludeFilter.xml myApp.jar However, a filter could also be used to select bug instances to specifically report: $ findbugs -textui -include myIncludeFilter.xml myApp.jar Match elements contain children, which are conjuncts of the predicate. In children must be true for the predicate to be true. 2. Types of Match clauses <Bug> other words, each of the This element specifies a particular bug pattern or patterns to match. The pattern attribute is a comma-separated list of bug pattern types. You can find the bug pattern types for particular warnings by looking at the output produced by the -xml output option (the type attribute of BugInstance elements), or from the bug descriptions document. For more coarse-grained matching, use code attribute. It takes a comma-separated list of bug abbreviations. For most-coarse grained matching use category attriute, that takes a comma separated list of bug category names: CORRECTNESS, MT_CORRECTNESS, BAD_PRACTICICE, PERFORMANCE, STYLE. If more than one of the attributes mentioned above are specified on the same <Bug> element, all bug patterns that match either one of specified pattern names, or abreviations, or categories will be matched. As a backwards compatibility measure, <BugPattern> and <BugCode> elements may be used instead of <Bug> element. Each of these uses a name attribute for specifying accepted values list. Support for these elements may be removed in a future release. <Priority> <Package> <Class> This element matches warnings with a particular priority. The value attribute should be an integer value: 1 to match high-priority warnings, 2 to match medium-priority warnings, or 3 to match lowpriority warnings. This element matches warnings associated with classes within the package specified using name attribute. Nested packages are not included (along the lines of Java import statement). However matching multiple packages can be achieved easily using regex name match. This element matches warnings associated with a particular class. The name attribute is used to specify the exact or regex match pattern for the class name. As a backward compatibility measure, instead of element of this type, you can use class attribute on a Match element to specify exact an class name or classregex attribute to specify a regular expression to match the class name against. If the Match element contains neither a Class element, nor a class / classregex attribute, the predicate will apply to all classes. Such predicate is likely to match more bug instances than you want, unless it is refined further down with apropriate method or field predicates. <Method> <Field> <Local> <Or> 3. Java element name matching If the name attribute of Class, Method or Field starts with the ~ character the rest of attribute content is interpreted as a Java regular expression that is matched against the names of the Java element in question. This element specifies a method. The name is used to specify the exact or regex match pattern for the method name. The params attribute is a comma-separated list of the types of the method's parameters. The returns attribute is the method's return type. In params and returns, class names must be fully qualified. (E.g., "java.lang.String" instead of just "String".) If one of the latter attributes is specified the other is required for creating a method signature. Note that you can provide either name attribute or params and returns attributes or all three of them. This way you can provide various kinds of name and signature based matches. This element specifies a field. The name attribute is is used to specify the exact or regex match pattern for the field name. You can also filter fields according to their signature - use type attribute to specify fully qualified type of the field. You can specify eiter or both of these attributes in order to perform name / signature based matches. This element specifies a local variable. The name attribute is is used to specify the exact or regex match pattern for the local variable name. Local variables are variables defined within a method. This element combines Match clauses as disjuncts. I.e., you can put two Method elements in an Or clause in order to match either method. Note that the pattern is matched against whole element name and therefore .* clauses need to be used at pattern beginning and/or end to perform substring matching. See java.util.regex.Pattern documentation for pattern syntax. 4. Caveats Match clauses can only match information that is actually contained in the bug instances. Every bug instance has a class, so in general, excluding bugs by class will work. Some bug instances have two (or more) classes. For example, the DE (dropped exception) bugs report both the class containing the method where the dropped exception happens, and the class which represents the type of the dropped exception. Only the first (primary) class is matched against Match clauses. So, for example, if you want to suppress IC (initialization circularity) reports for classes "com.foobar.A" and "com.foobar.B", you would use two Match clauses: <Match> <Class name="com.foobar.A" /> <Bug code="IC" /> </Match> <Match> <Class name="com.foobar.B" /> <Bug code="IC" /> </Match> By explicitly matching both classes, you ensure that the IC bug instance will be matched regardless of which class involved in the circularity happens to be listed first in the bug instance. (Of course, this approach might accidentally supress circularities involving "com.foobar.A" or "com.foobar.B" and a third class.) Many kinds of bugs report what method they occur in. For those bug instances, you can put Method clauses in the Match element and they should work as expected. 5. Examples 1. Match all bug reports for a class. <Match> <Class name="com.foobar.MyClass" /> </Match> 2. Match certain tests from a class by specifying their abbreviations. <Match> <Class name="com.foobar.MyClass"/ > <Bug code="DE,UrF,SIC" /> </Match> 3. Match certain tests from all classes by specifying their abbreviations. <Match> <Bug code="DE,UrF,SIC" /> </Match> 4. Match certain tests from all classes by specifying their category. <Match> <Bug category="PERFORMANCE" /> </Match> 5. Match bug types from specified methods of a class by their abbreviations. <Match> <Class name="com.foobar.MyClass" /> <Or> <Method name="frob" params="int,java.lang.String" returns="void" /> <Method name="blat" params="" returns="boolean" /> </Or> <Bug code="DC" /> </Match> 6. Match a particular bug pattern in a particular method. <!-- A method with an open stream false positive. --> <Match> <Class name="com.foobar.MyClass" /> <Method name="writeDataToFile" /> <Bug pattern="OS_OPEN_STREAM" /> </Match> 7. Match a particular bug pattern with a given priority in a particular method. <!-- A method with a dead local store false positive (medium priority). --> <Match> <Class name="com.foobar.MyClass" /> <Method name="someMethod" /> <Bug pattern="DLS_DEAD_LOCAL_STORE" /> <Priority value="2" /> </Match> 8. Match minor bugs introduced by AspectJ compiler (you are probably not interested in these unless you are an AspectJ developer). <Match> <Class name="~.*\$AjcClosure\d+" /> <Bug pattern="DLS_DEAD_LOCAL_STORE" /> <Method name="run" /> </Match> <Match> <Bug pattern="UUF_UNUSED_FIELD" /> <Field name="~ajc\$.*" /> </Match> 9. Match bugs in specific parts of the code base <!-- match unused fields warnings in Messages classes in all packages --> <Match> <Class name="~.*\.Messages" /> <Bug code="UUF" /> </Match> <!-- match mutable statics warnings in all internal packages --> <Match> <Package name="~.*\.internal" /> <Bug code="MS" /> </Match> <!-- match anonymoous inner classes warnings in ui package hierarchy --> <Match> <Package name="~com\.foobar\.fooproject\.ui.*" /> <Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON" /> </Match> 10. Match bugs on fieds or methods with specific signatures <!-- match System.exit(...) usage warnings in void main(String[]) methods in all classes --> <Match> <Method returns="void" name="main" params="java.lang.String[]" /> <Method pattern="DM_EXIT" /> </Match> <!-- match UuF warnings on fields of type com.foobar.DebugInfo on all classes -> <Match> <Field type="com.foobar.DebugInfo" /> <Bug code="UuF" /> </Match> 6. Complete Example <FindBugsFilter> <Match> <Class name="com.foobar.ClassNotToBeAnalyzed" /> </Match> <Match> <Class name="com.foobar.ClassWithSomeBugsMatched" /> <Bug code="DE,UrF,SIC" /> </Match> <!-- Match all XYZ violations. --> <Match> <Bug code="XYZ" /> </Match> <!-- Match all doublecheck violations in these methods of "AnotherClass". -> <Match> <Class name="com.foobar.AnotherClass" /> <Or> <Method name="nonOverloadedMethod" /> <Method name="frob" params="int,java.lang.String" returns="void" /> <Method name="blat" params="" returns="boolean" /> </Or> <Bug code="DC" /> </Match> <!-- A method with a dead local store false positive (medium priority). --> <Match> <Class name="com.foobar.MyClass" /> <Method name="someMethod" /> <Bug pattern="DLS_DEAD_LOCAL_STORE" /> <Priority value="2" /> </Match> </FindBugsFilter> Chapter 9. Analysis Properties FindBugs allows several aspects of the analyses it performs to be customized. System properties are used to configure these options. This chapter describes the configurable analysis options. The analysis options have two main purposes. First, they allow you to inform FindBugs about the meaning of methods in your application, so that it can produce more accurate results, or produce fewer false warnings. Second, they allow you to configure the precision of the analysis performed. Reducing analysis precision can save memory and analysis time, at the expense of missing some real bugs, or producing more false warnings. The analysis options are set using the -property command line option. For example: $ findbugs -textui -property "cfg.noprune=true" myApp.jar The list of configurable analysis properties is shown in Table 9.1, “Configurable Analysis Properties”. Table 9.1. Configurable Analysis Properties Property Name findbugs.assertionmethods findbugs.de.comment Value Meaning This property specifies the names of methods that are used to check program assertions. Specifying these Comma-separated list of fully qualified methods allows the null pointer method names: e.g., dereference bug detector to avoid "com.foo.MyClass.checkAssertion" reporting false warnings for values which are checked by assertion methods. true or false If true, the DroppedException detector scans source code for empty catch blocks for a comment, and if one is found, does not report a warning. findbugs.maskedfields.locals true or false If true, emit low priority warnings for local variables which obscure fields. Default is false. findbugs.nullderef.assumensp true or false not used (intention: If true, the null dereference detector assumes that any reference value returned from a method or passed to a method in a parameter might be null. Default is false. Note that enabling this property will very likely cause a large number of false warnings to be produced.) findbugs.refcomp.reportAll true or false If true, all suspicious reference comparisons using the == and != operators are reported. If false, only one such warning is issued per method. Default is false. true or false If true, the SwitchFallthrough detector will only report warnings for cases where the source code does not have a comment containing the words "fall" or "nobreak". (An accurate source path must be used for this feature to work correctly.) This helps find cases where the switch fallthrough is likely to be unintentional. findbugs.sf.comment Chapter 10. Annotations FindBugs supports several annotations to express the developer's intent so that FindBugs can issue warnings more appropriately. You need to use Java 5 to use annotations, and must place the annotations.jar and jsr305.jar files in the classpath while compiling your program. edu.umd.cs.findbugs.annotations.CheckForNull [Target] Field, Method, Parameter The annotated element might be null, and uses of the element should check for null. When this annotation is applied to a method it applies to the method return value. edu.umd.cs.findbugs.annotations.CheckReturnValue [Target] Method, Constructor [Parameter] priority:The priority of the warning (HIGH, MEDIUM, LOW, IGNORE). Default value:MEDIUM. explanation:A textual explaination of why the return value should be checked. Default value:"". This annotation is used to denote a method whose return value should always be checked after invoking the method. edu.umd.cs.findbugs.annotations.DefaultAnnotation [Target] Type, Package [Parameter] value:Annotation class objects. More than one class can be specified. priority:Default priority(HIGH, MEDIUM, LOW, IGNORE). Default value:MEDIUM. Indicates that all members of the class or package should be annotated with the default value of the supplied annotation classes. This would be used for behavior annotations such as @NonNull, @CheckForNull, or @CheckReturnValue. In particular, you can use @DefaultAnnotation(NonNull.class) on a class or package, and then use @Nullable only on those parameters, methods or fields that you want to allow to be null. edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields [Target] Type, Package [Parameter] value:Annotation class objects. More than one class can be specified. priority:Default priority(HIGH, MEDIUM, LOW, IGNORE). Default value:MEDIUM. This is same as the DefaultAnnotation except it only applys to fields. edu.umd.cs.findbugs.annotations.DefaultAnnotationForMethods [Target] Type, Package [Parameter] value:Annotation class objects. More than one class can be specified. priority:Default priority(HIGH, MEDIUM, LOW, IGNORE). Default value:MEDIUM. This is same as the DefaultAnnotation except it only applys to methods. edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters [Target] Type, Package [Parameter] value:Annotation class objects. More than one class can be specified. priority:Default priority(HIGH, MEDIUM, LOW, IGNORE). Default value:MEDIUM. This is same as the DefaultAnnotation except it only applys to method parameters. edu.umd.cs.findbugs.annotations.NonNull [Target] Field, Method, Parameter The annotated element must not be null. Annotated fields must not be null after construction has completed. Annotated methods must have non-null return values. edu.umd.cs.findbugs.annotations.Nullable [Target] Field, Method, Parameter The annotated element could be null under some circumstances. In general, this means developers will have to read the documentation to determine when a null value is acceptable and whether it is neccessary to check for a null value. FindBugs will treat the annotated items as though they had no annotation. In pratice this annotation is useful only for overriding an overarching NonNull annotation. edu.umd.cs.findbugs.annotations.OverrideMustInvoke [Target] Method [Parameter] value:Specify when the super invocation should be performed (FIRST, ANYTIME, LAST). Default value:ANYTIME. Used to annotate a method that, if overridden, must (or should) be invoke super in the overriding method. Examples of such methods include finalize() and clone(). The argument to the method indicates when the super invocation should occur: at any time, at the beginning of the overriding method, or at the end of the overriding method. (This anotation is not implmemented in FindBugs as of September 8, 2006). edu.umd.cs.findbugs.annotations.PossiblyNull This annotation is deprecated. Use CheckForNull instead. edu.umd.cs.findbugs.annotations.SuppressWarnings [Target] Type, Field, Method, Parameter, Constructor, Package [Parameter] value:The name of the warning. More than one name can be specified. justification:Reason why the warning should be ignored. Default value:"". The set of warnings that are to be suppressed by the compiler in the annotated element. Duplicate names are permitted. The second and successive occurrences of a name are ignored. The presence of unrecognized warning names is not an error: Compilers must ignore any warning names they do not recognize. They are, however, free to emit a warning if an annotation contains an unrecognized warning name. Compiler vendors should document the warning names they support in conjunction with this annotation type. They are encouraged to cooperate to ensure that the same names work across multiple compilers. edu.umd.cs.findbugs.annotations.UnknownNullness [Target] Field, Method, Parameter Used to indicate that the nullness of the target is unknown, or my vary in unknown ways in subclasses. edu.umd.cs.findbugs.annotations.UnknownNullness [Target] Field, Method, Parameter Used to indicate that the nullness of the target is unknown, or my vary in unknown ways in subclasses. FindBugs also supports the following annotations: net.jcip.annotations.GuardedBy net.jcip.annotations.Immutable net.jcip.annotations.NotThreadSafe net.jcip.annotations.ThreadSafe You can refer the JCIP annotation API documentation at Java Concurrency in Practice. Chapter 11. Using rejarForAnalysis If your project consists of many jarfiles or the jarfiles are scattered over many directories, you may wish to use the rejarForAnalysis script to make FindBugs invocation easier. The script collects many jarfiles and combines them into a single, large jarfile that can then be easily passed to FindBugs for analysis. This can be particularly useful in combination with the 'find' command on unix systems; e.g. find . -name '*.jar' | xargs rejarForAnalysis . The rejarForAnalysis script can also be used to split a very large project up into a set of jarfiles with the project classfiles evenly divided between them. This is useful when running FindBugs on the entire project is not practical due to time or memory consumption. Instead of running FindBugs on the entire project, you may use rejarForAnalysis build one large, all-inclusive jarfile containing all classes, invoke rejarForAnalysis again to split the project into multiple jarfiles, then run FindBugs on each divided jarfiles in turn, specifying the the all-inclusive jarfile in the -auxclasspath. These are the options accepted by the rejarForAnalysis script: -maxAge days Maximum age in days (ignore jar files older than this). -inputFileList filename Text file containing names of jar files. -maxClasses num Maximum number of classes per analysis*.jar file. -prefix class name prefix Prefix of class names that should be analyzed (e.g., edu.umd.cs.). Chapter 12. Data mining of bugs with FindBugs™ Table of Contents 1. Commands 2. Examples 3. Ant example 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. 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. 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 setBugDatabaseInfo (Section 1.7, “setBugDatabaseInfo”) command. 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 filterBugs command allows you to refer to a version by sequence number, name or timestamp. 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. 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 findbugs.lib refid is set correctly. Here is one way to set it: <!-- 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> 1. Commands 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. Briefly, the command-line tools are: unionBugs combine the results from separate analysis of disjoint classes computeBugHistory 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. setBugDatabaseInfo Set information such as the revision name or timestamp in an XML bug database listBugDatabaseInfo List information such as the revision name and timestamp for a list of XML bug databases filterBugs Select a subset of a bug database mineBugHistory Generate a tabular listing of the number of warnings in each version of a multiversion bug database defectDensity List information about defect density (warnings per 1000 NCSS) for the entire project and each class and package convertXmlToText Convert bug warnings in XML format to a textual one-line-per-bug format, or to HTML 1.1. unionBugs 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. Do not use this command to combine results from analyzing different versions of the same file; use computeBugHistory instead. Specify the xml files on the command line. The result is sent to standard output. 1.2. computeBugHistory 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). By default, output is written to the standard output. This functionality may also can be accessed from ant. First create a taskdef for computeBugHistory in your build file: <taskdef name="computeBugHistory" classname="edu.umd.cs.findbugs.anttask.ComputeBugHistoryTask"> <classpath refid="findbugs.lib" /> </taskdef> Attributes for this ant task are listed in the following table. To specify input files, nest them inside with a <datafile> element. For example: <computeBugHistory home="${findbugs.home}" ...> <datafile name="analyze1.xml"/> <datafile name="analyze2.xml"/> </computeBugHistory> Table 12.1. Options for computeBugHistory command Command-line option Ant attribute Meaning -output <file> output="<file>" save output in the named file (may also be an input file) override revision names for each version overrideRevisionNames="[true|false]" overrideRevisionNames[:truth] with names computed from the filenames -noPackageMoves[:truth] noPackageMoves="[true|false]" if a class has moved to another package, treat warnings in that class as seperate -preciseMatch[:truth] preciseMatch="[true|false]" require bug patterns to match precisely -precisePriorityMatch[:truth] precisePriorityMatch="[true|false]" consider two warnings as the same only if priorities match exactly -quiet[:truth] quiet="[true|false]" don't generate any output to standard out unless there is an error -withMessages[:truth] withMessages="[true|false]" include human-readable messages describing the warnings in XML output 1.3. filterBugs 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. This command takes a sequence of options, and either zero, one or two filenames of findbugs xml bug files on the command line. 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. This functionality may also can be accessed from ant. First create a taskdef for filterBugs in your build file: <taskdef name="filterBugs" classname="edu.umd.cs.findbugs.anttask.FilterBugsTask"> <classpath refid="findbugs.lib" /> </taskdef> 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 <datafile> element. For example: <filterBugs home="${findbugs.home}" ...> <datafile name="analyze.xml"/> </filterBugs> Table 12.2. Options for filterBugs command Command-line option Ant attribute Meaning input="<file>" use file as input output="<file>" output results to file -not not="[true|false]" reverse (all) switches for the filter -withSource[:truth] withSource="[true|false]" only warnings for switch source is available -exclude <filter file> exclude="<filter file>" exclude bugs matching given filter -include <filter file> include="<filter file>" include only bugs matching given filter -annotation <text> annotation="<text>" allow only warnings containing this text in a manual annotation -after <when> after="<when>" allow only warnings that first occurred after this version -before <when> before="<when>" allow only warnings that first occurred before this version -first <when> first="<when>" allow only warnings that first occurred in this version -last <when> last="<when>" allow only warnings that last occurred in this version -fixed <when> fixed="<when>" allow only warnings that last occurred in the previous version (clobbers -last) -present <when> present="<when>" allow only warnings present in this version -absent <when> absent="<when>" allow only warnings absent in this version -active[:truth] active="[true|false]" allow only warnings alive in the last sequence number allow only warnings introduced by a change of an introducedByChange="[true|false]" introducedByChange[:truth] existing class -removedByChange[:truth] removedByChange="[true|false]" allow only warnings removed by a change of a persisting class Command-line option Ant attribute Meaning -newCode[:truth] newCode="[true|false]" allow only warnings introduced by the addition of a new class -removedCode[:truth] removedCode="[true|false]" allow only warnings removed by removal of a class -priority <level> priority="<level>" allow only warnings with this priority or higher -class <pattern> class="<class>" allow only bugs whose primary class name matches this pattern -bugPattern <pattern> bugPattern="<pattern>" allow only bugs whose type matches this pattern -category <category> category="<category>" allow only warnings with a category that starts with this string -designation <designation> designation="<designation>" allow only warnings with this designation (e.g., designation SHOULD_FIX) -withMessages[:truth] withMessages="[true|false]" the generated XML should contain textual messages 1.4. mineBugHistory This command generates a table containing counts of the numbers of warnings in each version of a multiversion bug database. This functionality may also can be accessed from ant. First create a taskdef for mineBugHistory in your build file: <taskdef name="mineBugHistory" classname="edu.umd.cs.findbugs.anttask.MineBugHistoryTask"> <classpath refid="findbugs.lib" /> </taskdef> 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 <datafile> element. For example: <mineBugHistory home="${findbugs.home}" ...> <datafile name="analyze.xml"/> </mineBugHistory> Table 12.3. Options for mineBugHistory command Command-line option -formatDates Ant attribute Meaning input="<file>" use file as input output="<file>" write output to file formatDates="[true|false]" render dates in textual form Command-line option Ant attribute Meaning -noTabs noTabs="[true|false]" delimit columns with groups of spaces instead of tabs (see below) -summary summary="[true|false]" output terse summary of changes over the last ten entries The -noTabs 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 -formatDates to render dates in terser format without embedded whitespace. The table is a tab-separated (barring -noTabs) table with the following columns: Table 12.4. Columns in mineBugHistory output Title Meaning seq Sequence number (successive integers, starting at 0) version Version name time Release timestamp classes Number of classes analyzed NCSS Non Commenting Source Statements added Count of new warnings for a class that existed in the previous version newCode Count of new warnings for a class that did not exist in the previous version fixed Count of warnings removed from a class that remains in the current version removed Count of warnings in the previous version for a class that is not present in the current version retained Count of warnings that were in both the previous and current version dead Warnings that were present in earlier versions but in neither the current version or the immediately preceeding version active Total warnings present in the current version 1.5. defectDensity 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. 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. Table 12.5. Columns in defectDensity output Title Meaning Title Meaning kind project, package or class name The name of the project, package or class density Number of warnings generated per 1000 lines of NCSS. bugs Number of warnings NCSS Calculated number of NCSS 1.6. convertXmlToText This command converts a warning collection in XML format to a text format with one line per warning, or to HTML. This functionality may also can be accessed from ant. First create a taskdef for convertXmlToText in your build file: <taskdef name="convertXmlToText" classname="edu.umd.cs.findbugs.anttask.ConvertXmlToTextTask"> <classpath refid="findbugs.lib" /> </taskdef> Attributes for this ant task are listed in the following table. Table 12.6. Options for convertXmlToText command Command-line option -longBugCodes -html[:stylesheet] Ant attribute Meaning input="<filename>" use file as input output="<filename>" output results to file longBugCodes="[true|false]" use the full bug pattern code instead of two-letter abbreviation format="text" generate plain text output with one bug per line (command-line default) format="html:<stylesheet>" generate output with specified stylesheet (see below), or default.xsl if unspecified 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. 1.7. setBugDatabaseInfo This command sets meta-information in a specified warning collection. It takes the following options: This functionality may also can be accessed from ant. First create a taskdef for setBugDatabaseInfo in your build file: <taskdef name="setBugDatabaseInfo" classname="edu.umd.cs.findbugs.anttask.SetBugDatabaseInfoTask"> <classpath refid="findbugs.lib" /> </taskdef> 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 <datafile> element. For example: <setBugDatabaseInfo home="${findbugs.home}" ...> <datafile name="analyze.xml"/> </setBugDatabaseInfo> Table 12.7. setBugDatabaseInfo Options Command-line option -name <name> Ant attribute Meaning input="<file>" use file as input output="<file>" write output to file name="<name>" set name for (last) revision -timestamp <when> timestamp="<when>" set timestamp for (last) revision -source <directory> source="<directory>" add specified directory to the source search path -findSource <directory> findSource="<directory>" find and add all relevant source directions contained within specified directory -suppress <filter file> suppress="<filter file>" suppress warnings matched by this file (replaces previous suppressions) -withMessages withMessages="[true|false]" add textual messages to XML -resetSource resetSource="[true|false]" remove all source search paths 1.8. listBugDatabaseInfo 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. There is only one option: -formatDates renders dates in textual form. The output is a table one row per bug database and the following columns: Table 12.8. listBugDatabaseInfo Columns Column Meaning Column Meaning version version name time Release timestamp classes Number of classes analyzed NCSS Non Commenting Source Statements analyzed total Total number of warnings of all kinds high Total number of high priority warnings of all kinds medium Total number of medium/normal priority warnings of all kinds low Total number of low priority warnings of all kinds filename filename of database 2. Examples 2.1. Mining history using proveded shell scrips 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. You can use the command: computeBugHistory jdk1.6.0-b* | filterBugs -bugPattern IL_ | mineBugHistory formatDates to generate the following output: seq 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 version time dead active jdk1.6.0-b12 jdk1.6.0-b13 jdk1.6.0-b14 jdk1.6.0-b15 jdk1.6.0-b16 jdk1.6.0-b17 jdk1.6.0-b19 jdk1.6.0-b21 jdk1.6.0-b23 jdk1.6.0-b26 jdk1.6.0-b27 jdk1.6.0-b28 jdk1.6.0-b29 jdk1.6.0-b30 jdk1.6.0-b31 jdk1.6.0-b32 jdk1.6.0-b33 jdk1.6.0-b34 jdk1.6.0-b35 jdk1.6.0-b36 jdk1.6.0-b37 jdk1.6.0-b38 jdk1.6.0-b39 jdk1.6.0-b40 jdk1.6.0-b41 classes NCSS "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Fri "Thu "Thu Nov Nov Dec Dec Dec Dec Jan Jan Feb Mar Mar Mar Mar Mar Apr Apr Apr Apr May May May May Jun Jun Jun 11 18 02 09 16 23 13 27 10 03 10 17 24 31 07 14 21 28 05 12 19 26 03 09 16 added 09:07:20 06:02:06 06:12:26 06:07:04 06:21:28 06:27:22 06:41:16 05:57:52 05:44:36 06:04:02 04:48:38 02:54:22 03:09:20 02:53:32 03:00:14 02:56:56 02:46:22 02:49:00 02:49:04 02:59:46 02:55:08 03:08:16 03:10:48 03:30:28 03:19:22 newCode fixed EST EST EST EST EST EST EST EST EST EST EST EST EST EST EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT 2004" 2004" 2004" 2004" 2004" 2004" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 13128 13128 13145 13174 13175 13176 13176 13177 13179 13199 13189 13185 13117 13118 13117 13169 13187 13195 13457 13462 13464 13564 13856 15972 15972 removed retained 811569 811570 811786 811693 811715 811974 812011 812173 812188 811770 812440 812056 809468 809501 809572 811096 811942 813488 829837 831278 831971 836565 849992 959619 959619 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 2 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 jdk1.6.0-b42 jdk1.6.0-b43 jdk1.6.0-b44 jdk1.6.0-b45 jdk1.6.0-b46 jdk1.6.0-b47 jdk1.6.0-b48 jdk1.6.0-b49 jdk1.6.0-b50 jdk1.6.0-b51 jdk1.6.0-b52 jdk1.6.0-b53 jdk1.6.0-b54 jdk1.6.0-b55 jdk1.6.0-b56 jdk1.6.0-b57 jdk1.6.0-b58 jdk1.6.0-b59 jdk1.6.0-b60 "Fri "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu Jun Jul Jul Jul Aug Aug Aug Aug Sep Sep Sep Sep Sep Oct Oct Oct Oct Nov Nov 24 14 21 28 04 11 18 25 01 08 15 22 29 06 13 20 27 03 10 03:38:54 03:09:34 03:05:54 03:26:10 03:02:48 03:18:56 08:10:40 03:24:38 01:52:40 01:55:36 02:04:08 02:00:28 01:54:34 01:54:14 01:54:12 01:55:26 01:56:30 01:56:58 01:54:18 EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EST EST 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 15966 16041 16041 16037 15936 15964 15970 16048 16287 16362 16477 16019 16019 16051 16211 16279 16283 16232 16235 958581 960544 960547 960606 951355 952387 953421 958940 974937 979377 979399 957900 957900 959014 970835 971627 971945 972193 972346 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 We could also generate that information directly, without creating an intermediate db.xml file, using the command computeBugHistory jdk1.6.0-b*/jre/lib/rt.xml | filterBugs -bugPattern IL_ db.xml | mineBugHistory -formatDates 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. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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: filterBugs -priority M -category C db.xml | mineBugHistory -formatDates generating the table: seq 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 version time dead active jdk1.6.0-b12 jdk1.6.0-b13 jdk1.6.0-b14 jdk1.6.0-b15 jdk1.6.0-b16 jdk1.6.0-b17 jdk1.6.0-b19 jdk1.6.0-b21 jdk1.6.0-b23 jdk1.6.0-b26 jdk1.6.0-b27 jdk1.6.0-b28 jdk1.6.0-b29 jdk1.6.0-b30 jdk1.6.0-b31 jdk1.6.0-b32 jdk1.6.0-b33 jdk1.6.0-b34 jdk1.6.0-b35 jdk1.6.0-b36 jdk1.6.0-b37 jdk1.6.0-b38 jdk1.6.0-b39 jdk1.6.0-b40 jdk1.6.0-b41 jdk1.6.0-b42 jdk1.6.0-b43 jdk1.6.0-b44 jdk1.6.0-b45 jdk1.6.0-b46 jdk1.6.0-b47 jdk1.6.0-b48 jdk1.6.0-b49 jdk1.6.0-b50 jdk1.6.0-b51 jdk1.6.0-b52 jdk1.6.0-b53 jdk1.6.0-b54 jdk1.6.0-b55 jdk1.6.0-b56 jdk1.6.0-b57 jdk1.6.0-b58 jdk1.6.0-b59 jdk1.6.0-b60 jdk1.6.0-b61 classes NCSS "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Fri "Thu "Thu "Fri "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu "Thu Nov Nov Dec Dec Dec Dec Jan Jan Feb Mar Mar Mar Mar Mar Apr Apr Apr Apr May May May May Jun Jun Jun Jun Jul Jul Jul Aug Aug Aug Aug Sep Sep Sep Sep Sep Oct Oct Oct Oct Nov Nov Nov 11 18 02 09 16 23 13 27 10 03 10 17 24 31 07 14 21 28 05 12 19 26 03 09 16 24 14 21 28 04 11 18 25 01 08 15 22 29 06 13 20 27 03 10 17 added 09:07:20 06:02:06 06:12:26 06:07:04 06:21:28 06:27:22 06:41:16 05:57:52 05:44:36 06:04:02 04:48:38 02:54:22 03:09:20 02:53:32 03:00:14 02:56:56 02:46:22 02:49:00 02:49:04 02:59:46 02:55:08 03:08:16 03:10:48 03:30:28 03:19:22 03:38:54 03:09:34 03:05:54 03:26:10 03:02:48 03:18:56 08:10:40 03:24:38 01:52:40 01:55:36 02:04:08 02:00:28 01:54:34 01:54:14 01:54:12 01:55:26 01:56:30 01:56:58 01:54:18 01:58:42 newCode fixed EST EST EST EST EST EST EST EST EST EST EST EST EST EST EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EDT EST EST EST 2004" 2004" 2004" 2004" 2004" 2004" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 2005" 13128 13128 13145 13174 13175 13176 13176 13177 13179 13199 13189 13185 13117 13118 13117 13169 13187 13195 13457 13462 13464 13564 13856 15972 15972 15966 16041 16041 16037 15936 15964 15970 16048 16287 16362 16477 16019 16019 16051 16211 16279 16283 16232 16235 16202 removed retained 811569 811570 811786 811693 811715 811974 812011 812173 812188 811770 812440 812056 809468 809501 809572 811096 811942 813488 829837 831278 831971 836565 849992 959619 959619 958581 960544 960547 960606 951355 952387 953421 958940 974937 979377 979399 957900 957900 959014 970835 971627 971945 972193 972346 971134 0 0 3 2 0 0 0 0 0 0 1 0 3 0 0 1 3 0 0 0 0 1 6 7 0 3 5 0 19 13 163 0 1 19 1 0 13 0 1 6 0 0 6 0 2 1075 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 36 0 1 7 39 147 0 0 11 0 0 1 8 0 11 27 15 0 12 0 4 8 0 1 0 0 0 0 0 6 3 1 1 0 1 0 2 1 0 8 0 0 0 2 0 2 0 1 2 5 11 0 1 15 0 2 1 7 0 1 16 3 1 16 0 7 37 0 1 5 0 4 2.2. Incremental history maintenance 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: computeBugHistory -output db.xml db.xml jdk1.6.0-b61/jre/lib/rt.xml 3. Ant example 0 0 0 0 0 0 0 0 0 1 1 0 26 0 0 1 1 0 0 0 0 6 0 0 0 2 8 0 0 32 20 0 0 7 0 1 20 0 0 0 0 0 0 0 0 Here is a complete ant script example for both running findbugs and running a chain of data-mining tools afterward: <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> Chapter 13. License The name FindBugs and the FindBugs logo is trademarked by the University of Maryland. FindBugs is free software distributed under the terms of the Lesser GNU Public License. You should have received a copy of the license in the file LICENSE.txt in the FindBugs distribution. You can find the latest version of FindBugs, along with its source code, from the FindBugs web page. Chapter 14. Acknowledgments Table of Contents 1. Contributors 2. Software Used 1. Contributors FindBugs was originally written by Bill Pugh (<pugh@cs.umd.edu>). David Hovemeyer (<daveho@cs.umd.edu>) implemented some of the detectors, added the Swing GUI, and is a co-maintainer. Mike Fagan (<mfagan@tde.com>) contributed the Ant build script, the Ant task, and several enhancements and bug fixes to the GUI. Germano Leichsenring contributed Japanese translations of the bug summaries. David Li contributed the Emacs bug report format. Peter D. Stout contributed recursive detection of Class-Path attributes in analyzed Jar files, German translations of text used in the Swing GUI, and other fixes. Peter Friese wrote the FindBugs Eclipse plugin. Rohan Lloyd contributed several Mac OS X enhancements, bug detector improvements, and maintains the Fink package for FindBugs. Hiroshi Okugawa translated the FindBugs manual and more of the bug summaries into Japanese. Phil Crosby enhanced the Eclipse plugin to add a view to display the bug details. Dave Brosius fixed a number of bugs, added user preferences to the Swing GUI, improved several bug detectors, and contributed the string concatenation detector. Thomas Klaeger contributed a number of bug fixes and bug detector improvements. Andrei Loskutov made a number of improvements to the Eclipse plugin. Brian Goetz contributed a major refactoring of the visitor classes to improve readability and understandability. Pete Angstadt fixed several problems in the Swing GUI. Francis Lalonde provided a task resource file for the FindBugs Ant task. Garvin LeClaire contributed support for output in Xdocs format, for use by Maven. Holger Stenzhorn contributed improved German translations of items in the Swing GUI. Juha Knuutila contributed Finnish translations of items in the Swing GUI. Tanel Lebedev contributed Estonian translations of items in the Swing GUI. Hanai Shisei (ruimo) contributed full Japanese translations of bug messages, and text used in the Swing GUI. David Cotton contributed Fresh translations for bug messages and for the Swing GUI. Michael Tamm contributed support for the "errorProperty" attribute in the Ant task. Thomas Kuehne improved the German translation of the Swing GUI. Len Trigg improved source file support for the Emacs output mode. Greg Bentz provided a fix for the hashcode/equals detector. K. Hashimoto contributed internationalization fixes and several other bug fixes. Glenn Boysko contributed support for ignoring specified local variables in the dead local store detector. Jay Dunning contributed a detector to find equality comparisons of floating-point values, and overhauled the analysis summary report and its representation in the saved XML format. Olivier Parent contributed updated French translations for bug descriptions and Swing GUI. Chris Nappin contributed the plain.xsl stylesheet. Etienne Giraudy contributed the fancy.xsl and fancy-hist.xsl stylesheets, and made improvements to the -xml:withMessages option. Takashi Okamoto fixed bugs in the project preferences dialog in the Eclipse plugin, and contributed to its internationalization and localization. Thomas Einwaller fixed bugs in the project preferences dialog in the Eclipse plugin. Jeff Knox contributed support for the warningsProperty attribute in the Ant task. Peter Hendriks extended the Eclipse plugin preferences, and fixed a bug related to renaming the Eclipse plugin ID. Mark McKay contributed an Ant task to launch the findbugs frame. Dieter von Holten (dvholten) contributed some German improvements to findbugs_de.properties. If you have contributed to FindBugs, but aren't mentioned above, please send email to <findbugs@cs.umd.edu> (and also accept our humble apologies). 2. Software Used FindBugs uses several open-source software packages, without which its development would have been much more difficult. 2.1. BCEL FindBugs includes software developed by the Apache Software Foundation (http://www.apache.org/). Specifically, it uses the Byte Code Engineering Library. 2.2. ASM FindBugs uses the ASM bytecode framework, which is distributed under the following license: Copyright (c) 2000-2005 INRIA, France Telecom All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2.3. DOM4J FindBugs uses DOM4J, which is distributed under the following license: Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. Redistribution and use of this software and associated documentation ("Software"), with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain copyright statements and notices. Redistributions must also contain a copy of this document. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name "DOM4J" must not be used to endorse or promote products derived from this Software without prior written permission of MetaStuff, Ltd. For written permission, please contact <dom4jinfo@metastuff.com>. 4. Products derived from this Software may not be called "DOM4J" nor may "DOM4J" appear in their names without prior written permission of MetaStuff, Ltd. DOM4J is a registered trademark of MetaStuff, Ltd. 5. Due credit should be given to the DOM4J Project (http://dom4j.org/). THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.