- Blog Xebia France - -

Posted By Erwan Alliaume One on Wednesday, March 26th, 2008 14:11 In Java 2 Comments

The tools of static analysis of code allow to discern automatically some anomalies of an application. More anomalies are fast less discerned their cost of correction is high. Some people think that if the correction of a bug costs '1 ' during the stage of development, she will cost '10 ' in stage of recipe and '100 ' in production. The objectives of these tools are noble: discern a maximum of anomalies during the stage of development and reduce the number of bugs while returning more competitive and more homogeneous code. It is about one of the tools of which the developers have to guarantee the quality of their code. The most knowing and used in the world Popular dance are Checkstyle, PMD and FindBugs. allows, for example, to raise alerts in case of use of stocks _en dur_ in code while a constant would be the welcome. PMD discerns between others the presence of blocks wrestling spaces.. .. and FindBugs discerns the use of method equals on objects having no same type... David Hovemeyer and William Pugh, the creators of FindBugs, decided not to control the problems of style or of format and limit himself in search of true bugs... David Hovemeyer et William Pugh, les cr ateurs de FindBugs, ont d cid de ne pas contr ler les probl mes de style ou de format et de se limiter la recherche de v ritables bugs.

The main danger of this type of tool is to drown the developer in a crowd of information not corresponding to its need. Rules being predefined in general by these tools, they all cannot apply to all contexts. To avoid this bad analysis and the lifting of false positive, it is possible in general to configurer tools to hurry up, to deactivate or to change these rules at request.

Moreover, so consequent is, the number of rules offered remains limited. It would be however practical to add to the need our own rules to be of benefit in the best of these tools. It is what one we are going to make following the ticket. As usual addition is relatively well researched for and , we will be interested here in the creation of a new detector FindBugs.

FindBugs

FindBugs is therefore a tool of static analysis which examines classes in search of possible problems. To perform it, he analyses the bytecode in search of some known patterns. He does not limit itself to a research by regular expressions, he tries to understand what the programme wants to make.

A plugin FindBugs comes in the form of a regrouping file JAR one or several detectors. The standard given detectors are available in available JAR ' COREPLUGIN ' in the directory ' plugin ' of application. These same detectors will be you of a precious help. It is probably about the best available material on subject. That is why we deeply recommend you to draw inspiration from these before launching. There is indeed an existent detector which resembles future your.

During the starting of application, all present JAR in the file ' plugin ' is loaded to some following others. Following the ticket, we go, you will have understood him, create our own JAR and copy it in the same directory. By studying the existent detectors, you will point out that these spread, mostly, one of these two classes: BytecodeScanningDetector and BytecodePatternDetector. BytecodePatternDetector allows the detection of definite sequences of bytecode. It is easier to handle that his counterpart BytecodeScanningDetector but his use remains more limited. It is indeed why the most part of the existent detectors are based on this last (BytecodeScanningDetector). To manipulate the bytecode, FindBugs uses .

Detectors are based on the pattern visitor. In computer science of management, they have seldom opportunity to use this pattern, it occasions perhaps dreamt to use it in an adapted context. In any case, the creators of FindBugs of course chewed you job by giving you a realisation failing this one. You have only to overload desired methods.

Two methods interest us particularly:

  • visit (Code) is called by FindBugs during the course of the bytecode of a class.
  • sawOpcode (Int) is called by visit (), she allows to analyse every operation of the bytecode

Creation of a detector step by step

Let us plant the decor: following a massive and unjustified use of the class thread-safe StringBuffer, the technical representative in deciding to forbid the use to the advantage of the class StringBuilder, quicker. You are charging up to develop a detector FindBugs proving the application of this rule.

Disassemble an example

The first stage consists in creating a class example and in d compiler this one to see it a bytecode linked. This one will also serve you of class of test later. To disassemble a class, several choices present themselves to you. Either you use manually the order javap founie by the jdk, or you use a more convivial surcouche, as a plugin eclipse.

Here is our class of test:

public void useThem () {
  StringBuffer s1 = new StringBuffer ();
  StringBuilder s2 = new StringBuilder ();
}

The first line of method corresponds to the following bytecode:

L0
  LINENUMBER 11 L0
  new popular dance / lang / StringBuffer
  DUP
  INVOKESPECIAL popular dance / lang / StringBuffer. <init> () V
  ASTORE 1

Several options present themselves to us to forbid the use of StringBuffer. The simplest is to discern the instanciation. The following line of the bytecode 'new popular dance / lang / StringBuffer' interests us therefore particularly.

Surcharge of the visitor: creation of the detector

Let us begin by creating a class spreading BytecodeScanningDetector, class to which we will add a constructor taking in parametre BugReporter. As its name lets to guess, we will use this one later to add alerts.

Now that the skeleton of our detector is set up, it is time to be interested in its realisation. For it, we just need to overload sawOpcode method (). We raised before the bytecode who interests us: ' NEW ', let us filter code consequently. It remains then only to throw an alert of bug when that the op rande popular dance / lang / StringBuffer is discerned.

@Override
public void sawOpcode (int seen) {
 yew tree (seen == new) {
  yew tree (getClassConstantOperand ().equals ("popular dance / lang / StringBuffer ")) {
   BugInstance bug = new BugInstance (" XEBIA_STRINGBUFFER ", NORMAL_PRIORITY);
   //Before calling the sawOpcode (Int) method, the "visitor" updated the common authority of the class.
   //In that way, via reference this, it is possible to get information on the line of bytecode in the course of analysis
   bug.addClassAndMethod (This);
   bug.addSourceLine (This);
   bugReporter.reportBug (Bug);
  }
 }
}

The creation of an alert FindBugs passes by the creation of an object BugInstance. Two parametres passed in his constructor: a type and a priority. Type of bug corresponds in fact in a kind of identifying, we will reuse this one in following stages. It is also possible to link the bug to the common code. It will later allow to use some information of this one (of which the number of line) in messages describing anomaly.

Statement of the detector in the descripteur of plugin FindBugs

Let us pass to the creation of the descripteur of plugin. It is about a file XML that has to be in the directory " resource " in the root of JAR. His name is congealed: ' findbugs '. Let us declare first of all in this one our new detector. For it, it is enough to add a beacon containing information following the model below. Now that our detector is declared, we have not more than to add it to a category (CORRECTNESS, MALICIOUS_CODE, STYLE, PERFORMANCE). Here we use the category 'PERFORMANCE '.

<FindbugsPlugin>

 <Detector
  class = "fr.xebia.findbugs. XebiaNoStringBufferDetector"
  speed = "Fast" adjournments = "XEBIA_STRINGBUFFER"
 />

 
 <BugPattern abbrev = "XEB" portrays = category "XEBIA_STRINGBUFFER" = "PERFORMANCE"/>
 
</FindbugsPlugin>

Internationalisation of messages

Let us pass to the stage of translation of messages. It is here that we are going to translate different descriptions and character strings that we used until now in our example. Another file XML allows to perform it: 'messages '. Although his syntax is specific in FindBugs, his functioning remains identical to files i18n traditional. It is so possible to translate different resources into several languages by putting them in different files. For example, the file 'messages ' will be able to contain translation failing our detector (for example in English) and the file ' messages_fr ' will contain French translations.

<MessageCollection>

 <Plugin>
  <ShortDescription> Xebia FindBugs Plugins> </ShortDescription>
  <Details> Xebia FindBugs Plugins> </Details>
 </plugin>

 <Detector class = "fr.xebia.findbugs. XebiaNoStringBufferDetector">
  <Details> <! [CDATA [Call to StringBuffer]]> </Details>
 </Detector>

 <BugPattern portrays = "XEBIA_STRINGBUFFER">
  <ShortDescription> Call in StringBuffer </ShortDescription>
  <LongDescription> Call in StringBuffer in {1} </LongDescription>
  <Details>
    <! [CDATA [The call to StringBuffer is disadvised because
    ThreadSafe, use StringBuilder on the place]]>

  </Details>
 </BugPattern>

 <BugCode abbrev = "XEB"> Xebia FindBugs Plugins </BugCode>

</MessageCollection>

Display our plugin

We have not more than to generate JAR containing all that and to copy it in the directory ' plugin ' of FindBugs. Then, if you throw this one on the classes of test, you should obtain a similar result in the capture of screen below.

  • FindBugs discerned well our bugs thanks to our new detector
  • He classified them in the category "PERFORMANCE"
  • bugs is regrouped by "name" of plugin in this case "Xebia FindBugs Plugins" as we had defined him in the file "messages"
  • The detail of the bug contains, a general description of the bug met as well as the precise site of this one.
findbugs

Sources having served as a basis for this ticket are available:
you can download them with link below in the form of plan eclipse.


Telecharger plan eclipse


twitter erwan alliaume

Article printed from Blog Xebia France:

URL to article: / 2008 / 03 / 26 / ajouter-un-detecteur-personnalise-a-findbugs /

Click here to print.