Findbug编写新的规则

来源:互联网 发布:java 所有数据类型 编辑:程序博客网 时间:2024/05/17 07:31
最近用了下Findbug,想编写一个新的rule去扫描代码,防止开发用了非公用的log工具去打印log, 发现市面上关于这方面的资料非常少, 不是过期的就是错误太多了,对于刚上手的人来说很困难,这里把我学习的经历记录下方便自己熟悉,也希望能帮到想学习的同学.

其中大部分资料来自于<http://www.51testing.com/?uid-13997-action-spacelist-type-blog-starttime-1270339200-endtime-1270425600. >


首先去下载一个Findbug的源码包, 下载路径 http://sourceforge.net/projects/findbugs/files/findbugs/  

1. 我下载的时候最新的版本是2.0.2  下载文件 findbugs-2.0.2-source.zip即可. 下载完毕解压之后打开文件里面的build.xml . 把 depends 中含有 validate 的 validate值删除掉.然后用ant(需要配置ant的环境,晚上找下资料很多配置教程).  ant -buildfile build.xml去编译下工程.


2. 然后把工程导入eclipse. 直接import ->普通java工程就可以了.


3. 直接在导入的工程src 下面的 package edu.umd.cs.findbugs.detect 下面添加我们的测试ForbiddenSystemClass  

package edu.umd.cs.findbugs.detect;import org.apache.bcel.classfile.Code;import edu.umd.cs.findbugs.BugInstance;import edu.umd.cs.findbugs.BugReporter;import edu.umd.cs.findbugs.bcel.OpcodeStackDetector; /** * @author bo * 这个规则类用于判断System.out和System.error这种情况 */public class ForbiddenSystemClass extends OpcodeStackDetector { BugReporter bugReporter;  public ForbiddenSystemClass(BugReporter bugReporter) {  this.bugReporter = bugReporter; }  /**  * visit方法,在每次进入字节码方法的时候调用  * 在每次进入新方法的时候清空标志位  */ @Override public void visit(Code obj) {  super.visit(obj); }  /**  * 每扫描一条字节码就会进入sawOpcode方法  *  * @param seen  字节码的枚举值  */ @Override public void sawOpcode(int seen) {  if (seen == GETSTATIC) {   if (getClassConstantOperand().equals("java/lang/System")           && (getNameConstantOperand().equals("out") || getNameConstantOperand().equals("error"))) {    BugInstance bug = new BugInstance(this, "ALP_SYSTEMCLASS", NORMAL_PRIORITY).addClassAndMethod(this)            .addSourceLine(this, getPC());    bug.addInt(getPC());    bugReporter.reportBug(bug);   }  } }}


3. 然后再编辑etc下面的findbugs.xml 添加

<Detector class="edu.umd.cs.findbugs.detect.ForbiddenSystemClass"    speed="fast"     reports="ALP_SYSTEMCLASS"     hidden="false" /> <BugPattern abbrev="LIANGJZFORBIDDENSYSTEMCALSS" type="ALP_SYSTEMCLASS" category="EXPERIMENTAL"  />

如果报错, 就把Detector 跟BugPattern分别复制在 相应的区块内(跟其他同类型的定义放一块就行了.)

然后在编辑Message.xml


<Detector class="edu.umd.cs.findbugs.detect.ForbiddenSystemClass">   <Details>    <![CDATA[    <p>category:detector find System.out/System.error    <p>please use log4j    ]]>   </Details>  </Detector> <BugPattern type="ALP_SYSTEMCLASS">    <ShortDescription>short desc:System.out/error</ShortDescription>    <LongDescription>class={0},method {1}long desc:System.out,please use log4j</LongDescription>    <Details>  <![CDATA[    <p>detail info see log4j document</p>  ]]>    </Details>  </BugPattern>


同样如果报错, 就把Detector 跟BugPattern分别复制在 相应的区块内(跟其他同类型的定义放一块就行了.)


4. 重新运行ant -buildfile build.xml 去重新编译工程. 然后找到 bin文件下 运行findbugs.bat gui版本去测试下我们的添加是否生效.  新建->选择测试类编译后的.class文件目录.

测试类工程代码是

public class Example {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stub        String str="pass";             if(str.equals("pass")){                 System.out.println("str is pass");            System.err.append("haha");        }}}

运行查看结果是否有我们刚才定义的错误

5.最后如果想在Eclipse中集成规则

替换文件用winrar打开D:\devtools\eclipse_3.5.1\plugins\edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821\findbugs-plugin.jar;中message.xml,findbugs.xml,加入二进制的edu.umd.cs.findbugs.detect. ForbiddenSystemClass重启elipse,还需要确保experimental类的错误能在findbugs窗口展现windows-preferences-java-findbugs-reporter configuration上的experimental选项勾上编写规则需要对字节码比较熟悉.

原创粉丝点击