Adding Detectors to FindBugs
May 12, 2003
Updated June 6, 2003 (detector meta-information, cleanups)

===============
1. Introduction
===============

FindBugs uses a plugin-based approach to adding detectors.
This makes it easy for users to add their own detectors alongside
the ones that come built in.

Basic idea: FindBugs has some Jar files in a "plugins" directory.
At startup, each of those jar files is checked for a "findbugs.xml"
file.  That XML file registers instances of Detectors, as well
as particular "bug patterns" that the detector reports.

Additionally to the findbugs.xml, bugrank.txt and messages.xml files are
required for each FindBugs detector plugin.

At startup, FindBugs loads all plugin Jar files.  At analysis time,
all detectors named in the findbugs.xml files from those plugins
are instantiated and applied to analyzed class files.

In order to format reported BugInstances as text for display,
a messages file is loaded from the plugin.  In order to support multiple
language translations, a locale search is performed in a manner
similar to the handling of resource bundles.  For example, if the
locale is "pt_BR", then the files

  messages_pt_BR.xml
  messages_pt.xml
  messages.xml

are tried, in that order.

The "findbugs.xml" and "messages.xml" files used by the standard FindBugs
bug pattern detectors (coreplugin.jar) can be found in the "etc" directory
of the findbugs source distribution. Both files must be UTF-8 encoded.


============================
2. Example findbugs.xml file
============================

<DetectorPlugin>

  <Detector class="org.foobar.findbugs.FindUnreleasedLocks" speed="slow" />
  <Detector class="org.foobar.findbugs.ExperimentalDetector" speed="fast" disabled="true" />

  <!-- More Detector elements would go here... -->

  <BugPattern type="UBL_UNRELEASED_LOCK" abbrev="UL" category="MT_CORRECTNESS" />

  <!-- More BugPattern elements would go here... -->

</DetectorPlugin>


======================================
3. Meaning of elements in findbugs.xml
======================================

  <DetectorPlugin> a collection of <Detector> and <BugPattern> elements.
  Each plugin Jar file can (and usually will) provide multiple detectors
  and define multiple bug patterns.

  <Detector> specifies a class which implements the edu.umd.cs.findbugs.Detector
  interface and has a constructor that takes a single parameter of type
  edu.umd.cs.findbugs.BugReporter.  This element has three possible attributes:

    1. The required "class" attribute specifies the Detector class.

    2. The optional "disabled" attribute, if set to "true", means
       that by default, the detector will be disabled at runtime.
       This is useful for detectors that aren't quite ready for prime time.

    3. The required "speed" attribute supplies a value to be shown in the
       "Settings->Configure Detectors" dialog.  It gives the user an idea of
       how expensive the analysis will be to perform.  The value of this
       attribute should be one of "fast", "moderate", or "slow".

  <BugPattern> specifies a kind of bug that will be reported.
  It has three required attributes:

    1. "type" is a unique code identifying the bug.  Only one BugPattern
       can have a a particular type.

    2. "abbrev" is a short alphanumeric code for the bug.
       Note that multiple BugPatterns can use the same abbreviation
       if they are related.  (See the BugCode element in messages.xml).

    3. "category" can be one of categories defined in the core plugin's messages.xml:

       CORRECTNESS - code that was probably not what the developer intended
       BAD_PRACTICE - violations of recommended and essential coding practice
       STYLE - code that is confusing, anomalous, or written in a way that that leads itself to errors
       MT_CORRECTNESS - multithreaded correctness issues
       MALICIOUS_CODE - a potential vulnerability if exposed to malicious code
       PERFORMANCE - a performance issue
       I18N - internationalization and locale

       or you may create your own category, in which case you should define
       it in a <BugCategory> element in _your_ messages.xml file.

============================
4. Example messages.xml file
============================

<MessageCollection>

  <Detector class="org.foobar.findbugs.FindUnreleasedLocks" >
    <Details>
      <![CDATA[
        <p> This detector looks for JSR-166 locks that are not released on all paths
        out of a method.  Because it performs dataflow analysis, it is fairly slow.
      ]]>
    </Details>
  </Detector>

  <!-- More Detector nodes would go here... -->

  <BugPattern type="UBL_UNRELEASED_LOCK">
    <ShortDescription>Lock not released on all paths out of method</ShortDescription>

    <LongDescription>{1} does not release lock on all paths out of method</LongDescription>

    <Details>
      <![CDATA[
        <p> A JSR-166 lock acquired in this method is not released on all paths
        out of the method. This could result in a deadlock if another thread
        tries to acquire the lock.  Generally, you should use a finally
        block to ensure that acquired locks are always released.
      ]]>
    </Details>
  </BugPattern>

  <!-- More BugPattern nodes would go here... -->

  <BugCode abbrev="UL">Unreleased locks</BugCode>

  <!-- More BugCode nodes would go here... -->

</MessageCollection>


======================================
5. Meaning of elements in messages.xml
======================================

  <MessageCollection> is the top level element

  <BugCategory> elements optionally describe any categories you
  may have created for your bug patterns. You can skip these if
  you are using only the categories defined by the core plugin.

    The <Description> child element has a brief (a word or three)
    description of the category. The <Abbreviation> child element
    is typically a single capital latter. The optional <Details>
    child element may describe it in more detail (but no markup).

  <Detector> holds meta-information about a Detector in the plugin.
  The required "class" attribute specifies the Detector class.
  Detector elements much have the following child elements:

    The <Details> child element has a brief HTML description of the Detector.
    It should have HTML markup that would be valid in a BODY element.
    It should be specified in a CDATA section so that the HTML
    tags are not misinterpreted as XML.

  <BugPattern> holds all of the human-readable messages for the bug pattern
  identified by the "type" attribute.  The type corresponds to the
  type attribute of the BugPattern elements described in findbugs.xml.
  BugPattern elements must have the following child elements:

    <ShortDescription> this is used for when "View->Full Descriptions"
    is turned off in the GUI, and it's also used as the title for
    descriptions in the Details window.

    <LongDescription> this is used for when "View->Full Descriptions"
    is turned on in the GUI, and for output using the command line UI.
    The placeholders in the long description ({0}, {1}, etc.)
    refer to BugAnnotations attached to the BugInstances reported by
    the detector for this bug pattern. You may also use constructs
    like {1.name} or {1.returnType}.

    <Details> this is the descriptive text to be used in the Details
    window.  It consists of HTML markup to appear in the BODY element of an HTML
    document.  It should be specified in a CDATA section so that the HTML
    tags are not misinterpreted as XML.

    <BugCode> is the text which describes the common characteristic of all
    of the BugPatterns which share an abbreviation.  In the example above,
    the abbreviation "UL" is for bugs in which a lock is not released.
    The text of a BugCode element is shown for tree nodes in the GUI
    which group bug instances by "bug type".

======================================
6. Meaning of elements in bugrank.txt
======================================

For the detailed and up to date information, please read the javadoc of the
edu.umd.cs.findbugs.BugRanker class.

============================================
7. Using 3rd party libraries in the detector
============================================

FindBugs plugins may extend the default FindBugs classpath and use custom 3rd party
libraries during the analysis. This libraries must be part of standard jar class path
specified via "ClassPath" attribute in the META-INF/MANIFEST.MF file.

======================================
8. Adding detectors to Eclipse plugin
======================================

Since version 2.0.0 Eclipse plugin allows to configure or contribute custom detectors.

7.1. It is possible to contribute custom detectors via standard Eclipse extensions mechanism.
Please check the documentation of the "findBugsEclipsePlugin/schema/detectorPlugins.exsd"
extension point how to update the plugin.xml. Existing FindBugs detector plugins can
be easily "extended" to be full featured FindBugs & Eclipse detector plugins.
Usually you only need to add META-INF/MANIFEST.MF and plugin.xml to the jar and
update your build scripts to not to override the MANIFEST.MF during the build.

7.2 It is possible to configure custom detectors via Eclipse workspace preferences.
Go to "Window->Preferences->Java->FindBugs->Misc. Settings->Custom Detectors"
and specify there locations of any additional plugin libraries.

7.3 Plugins contributed via standard Eclipse extensions mechanism (see 7.1)
may extend the default FindBugs classpath and use custom libraries during the analysis.
This libraries must be part of standard Eclipse plugin dependencies specified via
either "Require-Bundle" or "Bundle-ClassPath" attributes in the MANIFEST.MF file.
In case custom detectors need access to this custom libraries at runtime, an
extra line must be added to the MANIFEST.MF (without quotation marks):
"Eclipse-RegisterBuddy: edu.umd.cs.findbugs.plugin.eclipse".

