Home | History | Annotate | Download | only in doc
      1 Adding Detectors to FindBugs
      2 May 12, 2003
      3 Updated June 6, 2003 (detector meta-information, cleanups)
      4 
      5 ===============
      6 1. Introduction
      7 ===============
      8 
      9 FindBugs uses a plugin-based approach to adding detectors.
     10 This makes it easy for users to add their own detectors alongside
     11 the ones that come built in.
     12 
     13 Basic idea: FindBugs has some Jar files in a "plugins" directory.
     14 At startup, each of those jar files is checked for a "findbugs.xml"
     15 file.  That XML file registers instances of Detectors, as well
     16 as particular "bug patterns" that the detector reports.
     17 
     18 Additionally to the findbugs.xml, bugrank.txt and messages.xml files are
     19 required for each FindBugs detector plugin.
     20 
     21 At startup, FindBugs loads all plugin Jar files.  At analysis time,
     22 all detectors named in the findbugs.xml files from those plugins
     23 are instantiated and applied to analyzed class files.
     24 
     25 In order to format reported BugInstances as text for display,
     26 a messages file is loaded from the plugin.  In order to support multiple
     27 language translations, a locale search is performed in a manner
     28 similar to the handling of resource bundles.  For example, if the
     29 locale is "pt_BR", then the files
     30 
     31   messages_pt_BR.xml
     32   messages_pt.xml
     33   messages.xml
     34 
     35 are tried, in that order.
     36 
     37 The "findbugs.xml" and "messages.xml" files used by the standard FindBugs
     38 bug pattern detectors (coreplugin.jar) can be found in the "etc" directory
     39 of the findbugs source distribution. Both files must be UTF-8 encoded.
     40 
     41 
     42 ============================
     43 2. Example findbugs.xml file
     44 ============================
     45 
     46 <DetectorPlugin>
     47 
     48   <Detector class="org.foobar.findbugs.FindUnreleasedLocks" speed="slow" />
     49   <Detector class="org.foobar.findbugs.ExperimentalDetector" speed="fast" disabled="true" />
     50 
     51   <!-- More Detector elements would go here... -->
     52 
     53   <BugPattern type="UBL_UNRELEASED_LOCK" abbrev="UL" category="MT_CORRECTNESS" />
     54 
     55   <!-- More BugPattern elements would go here... -->
     56 
     57 </DetectorPlugin>
     58 
     59 
     60 ======================================
     61 3. Meaning of elements in findbugs.xml
     62 ======================================
     63 
     64   <DetectorPlugin> a collection of <Detector> and <BugPattern> elements.
     65   Each plugin Jar file can (and usually will) provide multiple detectors
     66   and define multiple bug patterns.
     67 
     68   <Detector> specifies a class which implements the edu.umd.cs.findbugs.Detector
     69   interface and has a constructor that takes a single parameter of type
     70   edu.umd.cs.findbugs.BugReporter.  This element has three possible attributes:
     71 
     72     1. The required "class" attribute specifies the Detector class.
     73 
     74     2. The optional "disabled" attribute, if set to "true", means
     75        that by default, the detector will be disabled at runtime.
     76        This is useful for detectors that aren't quite ready for prime time.
     77 
     78     3. The required "speed" attribute supplies a value to be shown in the
     79        "Settings->Configure Detectors" dialog.  It gives the user an idea of
     80        how expensive the analysis will be to perform.  The value of this
     81        attribute should be one of "fast", "moderate", or "slow".
     82 
     83   <BugPattern> specifies a kind of bug that will be reported.
     84   It has three required attributes:
     85 
     86     1. "type" is a unique code identifying the bug.  Only one BugPattern
     87        can have a a particular type.
     88 
     89     2. "abbrev" is a short alphanumeric code for the bug.
     90        Note that multiple BugPatterns can use the same abbreviation
     91        if they are related.  (See the BugCode element in messages.xml).
     92 
     93     3. "category" can be one of categories defined in the core plugin's messages.xml:
     94 
     95        CORRECTNESS - code that was probably not what the developer intended
     96        BAD_PRACTICE - violations of recommended and essential coding practice
     97        STYLE - code that is confusing, anomalous, or written in a way that that leads itself to errors
     98        MT_CORRECTNESS - multithreaded correctness issues
     99        MALICIOUS_CODE - a potential vulnerability if exposed to malicious code
    100        PERFORMANCE - a performance issue
    101        I18N - internationalization and locale
    102 
    103        or you may create your own category, in which case you should define
    104        it in a <BugCategory> element in _your_ messages.xml file.
    105 
    106 ============================
    107 4. Example messages.xml file
    108 ============================
    109 
    110 <MessageCollection>
    111 
    112   <Detector class="org.foobar.findbugs.FindUnreleasedLocks" >
    113     <Details>
    114       <![CDATA[
    115         <p> This detector looks for JSR-166 locks that are not released on all paths
    116         out of a method.  Because it performs dataflow analysis, it is fairly slow.
    117       ]]>
    118     </Details>
    119   </Detector>
    120 
    121   <!-- More Detector nodes would go here... -->
    122 
    123   <BugPattern type="UBL_UNRELEASED_LOCK">
    124     <ShortDescription>Lock not released on all paths out of method</ShortDescription>
    125 
    126     <LongDescription>{1} does not release lock on all paths out of method</LongDescription>
    127 
    128     <Details>
    129       <![CDATA[
    130         <p> A JSR-166 lock acquired in this method is not released on all paths
    131         out of the method. This could result in a deadlock if another thread
    132         tries to acquire the lock.  Generally, you should use a finally
    133         block to ensure that acquired locks are always released.
    134       ]]>
    135     </Details>
    136   </BugPattern>
    137 
    138   <!-- More BugPattern nodes would go here... -->
    139 
    140   <BugCode abbrev="UL">Unreleased locks</BugCode>
    141 
    142   <!-- More BugCode nodes would go here... -->
    143 
    144 </MessageCollection>
    145 
    146 
    147 ======================================
    148 5. Meaning of elements in messages.xml
    149 ======================================
    150 
    151   <MessageCollection> is the top level element
    152 
    153   <BugCategory> elements optionally describe any categories you
    154   may have created for your bug patterns. You can skip these if
    155   you are using only the categories defined by the core plugin.
    156 
    157     The <Description> child element has a brief (a word or three)
    158     description of the category. The <Abbreviation> child element
    159     is typically a single capital latter. The optional <Details>
    160     child element may describe it in more detail (but no markup).
    161 
    162   <Detector> holds meta-information about a Detector in the plugin.
    163   The required "class" attribute specifies the Detector class.
    164   Detector elements much have the following child elements:
    165 
    166     The <Details> child element has a brief HTML description of the Detector.
    167     It should have HTML markup that would be valid in a BODY element.
    168     It should be specified in a CDATA section so that the HTML
    169     tags are not misinterpreted as XML.
    170 
    171   <BugPattern> holds all of the human-readable messages for the bug pattern
    172   identified by the "type" attribute.  The type corresponds to the
    173   type attribute of the BugPattern elements described in findbugs.xml.
    174   BugPattern elements must have the following child elements:
    175 
    176     <ShortDescription> this is used for when "View->Full Descriptions"
    177     is turned off in the GUI, and it's also used as the title for
    178     descriptions in the Details window.
    179 
    180     <LongDescription> this is used for when "View->Full Descriptions"
    181     is turned on in the GUI, and for output using the command line UI.
    182     The placeholders in the long description ({0}, {1}, etc.)
    183     refer to BugAnnotations attached to the BugInstances reported by
    184     the detector for this bug pattern. You may also use constructs
    185     like {1.name} or {1.returnType}.
    186 
    187     <Details> this is the descriptive text to be used in the Details
    188     window.  It consists of HTML markup to appear in the BODY element of an HTML
    189     document.  It should be specified in a CDATA section so that the HTML
    190     tags are not misinterpreted as XML.
    191 
    192     <BugCode> is the text which describes the common characteristic of all
    193     of the BugPatterns which share an abbreviation.  In the example above,
    194     the abbreviation "UL" is for bugs in which a lock is not released.
    195     The text of a BugCode element is shown for tree nodes in the GUI
    196     which group bug instances by "bug type".
    197 
    198 ======================================
    199 6. Meaning of elements in bugrank.txt
    200 ======================================
    201 
    202 For the detailed and up to date information, please read the javadoc of the
    203 edu.umd.cs.findbugs.BugRanker class.
    204 
    205 ============================================
    206 7. Using 3rd party libraries in the detector
    207 ============================================
    208 
    209 FindBugs plugins may extend the default FindBugs classpath and use custom 3rd party
    210 libraries during the analysis. This libraries must be part of standard jar class path
    211 specified via "ClassPath" attribute in the META-INF/MANIFEST.MF file.
    212 
    213 ======================================
    214 8. Adding detectors to Eclipse plugin
    215 ======================================
    216 
    217 Since version 2.0.0 Eclipse plugin allows to configure or contribute custom detectors.
    218 
    219 7.1. It is possible to contribute custom detectors via standard Eclipse extensions mechanism.
    220 Please check the documentation of the "findBugsEclipsePlugin/schema/detectorPlugins.exsd"
    221 extension point how to update the plugin.xml. Existing FindBugs detector plugins can
    222 be easily "extended" to be full featured FindBugs & Eclipse detector plugins.
    223 Usually you only need to add META-INF/MANIFEST.MF and plugin.xml to the jar and
    224 update your build scripts to not to override the MANIFEST.MF during the build.
    225 
    226 7.2 It is possible to configure custom detectors via Eclipse workspace preferences.
    227 Go to "Window->Preferences->Java->FindBugs->Misc. Settings->Custom Detectors"
    228 and specify there locations of any additional plugin libraries.
    229 
    230 7.3 Plugins contributed via standard Eclipse extensions mechanism (see 7.1)
    231 may extend the default FindBugs classpath and use custom libraries during the analysis.
    232 This libraries must be part of standard Eclipse plugin dependencies specified via
    233 either "Require-Bundle" or "Bundle-ClassPath" attributes in the MANIFEST.MF file.
    234 In case custom detectors need access to this custom libraries at runtime, an
    235 extra line must be added to the MANIFEST.MF (without quotation marks):
    236 "Eclipse-RegisterBuddy: edu.umd.cs.findbugs.plugin.eclipse".
    237 
    238