Custom Detectors for FindBugs (London Java Community Unconference 2)


Published on

Slides for presentation / demo for a basic introduction to writing custom detectors for FindBugs.

Talk was given at the London Java Community Unconference 2, 26th June 2010.

The example code that goes with the slides is here:

Published in: Technology, Education
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Custom Detectors for FindBugs (London Java Community Unconference 2)

  1. 1. A basic introduction to Writing Custom Detectors for FindBugs
  2. 2. FindBugs <ul><li>Static analysis tool for Java
  3. 3. Detects suspicious patterns in code </li><ul><li>-> See </li></ul><li>Detectors for ~370 bug types </li><ul><li>-> See bug list </li></ul><li>Use filters to select specific sets of detectors </li></ul>What's Findbugs?
  4. 4. <ul><li>Run as... </li><ul><li>IDE plugin
  5. 5. Ant task – part of Continuous Integration build
  6. 6. Standalone app (CLI or UI) </li></ul><li>Operates on Java ByteCode, so you can analyse: </li><ul><li>Your compiled Java code
  7. 7. Dependent libraries (binaries)
  8. 8. Other JVM languages, compiled to ByteCode? </li></ul></ul>FindBugs What's Findbugs?
  9. 9. <ul><li>Enforce a project-specific constraint, e.g.: </li><ul><li>Ensure all logging is guarded
  10. 10. Flag common API misuses
  11. 11. Environment/platform-specific constraints
  12. 12. Enforce naming conventions </li></ul><li>You've identified a new, general bug pattern: </li><ul><li>A common misuse of a JCL API
  13. 13. A sequence of operations that is doomed to fail </li></ul></ul>Custom Detectors Why create a custom detector?
  14. 14. <ul><li>A plugin is a jar file containing at least 3 files: </li><ul><li>findbugs.xml
  15. 15. messages.xml
  16. 16. A detector class </li></ul><li>FindBugs loads plugin jars from its “plugin” directory. </li></ul><ul><li>One plugin jar can contain multiple detector classes.
  17. 17. One detector class can report multiple bug types. </li></ul>Custom Detectors FindBugs Plugins
  18. 18. Custom Detectors The XML files <ul>-> See examples </ul>
  19. 19. The Detector Class The Most Simple Detector... public class MyDetector implements Detector { private BugReporter reporter ; /** Instantiated when analysis starts. */ public MyDetector (BugReporter reporter) { this . reporter = reporter; } /** Invoked for every class to analyse */ @Override public void visitClassContext(ClassContext classContext) { } /** Invoked after all classes have been analysed by all detectors. */ @Override public void report() { } } <ul>-> Examples </ul>
  20. 20. The Detector Class Visitors & Detectors Visitor visit(class) visit(const) visit(field) visit(method) … state <ul>-> Examples </ul>
  21. 21. <ul><li>A character set used on IBM mainframes.
  22. 22. Usually pronounced eb-sih-dic.
  23. 23. It is not ASCII-compatible.
  24. 24. … but it becomes relevant when your code runs in an IBM mainframe! </li></ul>The EBCDIC Issue What's EBCDIC? “ EBCDIC is not relevant to your life.” -Joel Spolsky
  25. 25. <ul><li>Programs often convert between bytes and character data </li><ul><li>Writing/reading text to/from the file system
  26. 26. Sending/receiving text over the network </li></ul><li>Such conversions always use a character set, e.g.: </li></ul>The EBCDIC Issue é [0xC3, 0xA9] [0xE9] Text Byte value Charset Character Sets
  27. 27. <ul><li>In Java, if no charset is specified, a default is used.
  28. 28. The default is platform-specific. </li></ul>The EBCDIC Issue hello [0x68,0x65,0x6C,0x6C,0x6F] Default Charset in Java String s1 = new String(myByteArray, Charset.forName( &quot;UTF-8&quot; )); // Uses UTF-8 String s2 = new String( myByteArray ); // Uses default charset <ul><li>On most platforms, this default is “ASCII-compatible”: </li></ul>These characters have the same byte value in all ASCII-compatible Character sets.
  29. 29. <ul><li>EBCDIC is not ASCII-compatible.
  30. 30. Imagine you're sending bytes over the network and the client is expecting ISO8859-1 text:
  31. 31. On ASCII-compatible platforms , the code above sends the correct ISO8859-1 bytes for HELLO .
  32. 32. On z/OS , it sends data that ISO88591-decodes to: ÈÅÓÓÖ
  33. 33. The code should look something like: </li></ul>The EBCDIC Issue If you �Unicode, you’ll �����EBCDIC connection.getOutputStream().write( &quot;HELLO&quot; .getBytes()); connection.getOutputStream().write( &quot;HELLO&quot; .getBytes( &quot; ISO8859-1 &quot; ));
  34. 34. <ul><li>The file.encoding system property can be used to change the default.
  35. 35. Not a suitable solution if different libraries make different assumptions about the default.
  36. 36. Can be useful for testing that your code works OK in an EBCDIC environment, e.g.: </li></ul>The EBCDIC Issue -Dfile.encoding <ul>java -Dfile.encoding=IBM-1047 -Dconsole.encoding=ISO8859-1 ... </ul>
  37. 37. The EBCDIC Issue Affected Java Class Library Methods java.lang.String.getBytes() java.lang.String(byte[] bytes) filename) file) fileDescriptor) filename) file) fileDescriptor) input) output) file) output) string) file) output) string) java.util.Scanner(InputStream input) java.util.Formatter(String filename) java.util.Formatter(File file) java.util.Formatter(OutputStream output)
  38. 38. -> See code. Default Encoding Detector Implementation of the default encoding detector
  39. 39. <ul><li>BugAccumulator: helps avoid reporting same bug many times
  40. 40. Class metadata and identifiers : </li><ul><li>XClass, ClassDescriptor, JavaClass (BCEL)
  41. 41. XMethod, MethodDescriptor, Method (BCEL)
  42. 42. ... </li></ul><li>AnnotationDatabase: helps to simplify marking interesting classes, methods, fields... and identify their usage.
  43. 43. StatelessDetector: Marker interface – detector is cloned on each class so any state that is not cloned can be GC'd
  44. 44. DataflowAnalysis: Provides access to a c ontrol flow graph </li></ul>More FindBugs Classes
  45. 45. <ul><li>Examine the built-in detectors </li><ul><li>Find one that detects a pattern similar to yours. </li></ul><li>Write tests for your detector. </li><ul><li>Run Findbugs on test data, compare report against baseline .
  46. 46. Or see this blog post for a lighter approach. </li><ul><li>-> Example using annotations to mark expected bugs </li></ul></ul><li>Build and test your custom detector as part of your CI. </li><ul><li>Ensures freshest, correct version is always used. </li></ul><li>Don't be put off by ByteCode </li><ul><li>Use this ByteCode Viewer plugin for Eclipse. </li></ul></ul>Misc. Tips
  47. 47. This presentation: Today's code: Encoding detector: References / further reading / tools: <ul><li>developerWorks article about custom detectors:
  48. 48. Daniel Schneller's blog posts about custom detectors:
  49. 49. Josh Cummings' blog post about testing detectors:
  50. 50. ByteCode Outline plugin for Eclipse:
  51. 51. FindBugs Mailing List </li></ul>Links