代码静态检查之findbugs


白盒测试中的静态检查一般是检查编码标准规范,错误列表。编码规范往往团队会根据自己的经验和风格进行设置一些规范。现在很多IDE工具都会在编辑代码的时候实时的提醒是否符合代码风格。错误列表,一般是代码潜在的bug,由于某种代码写法虽然没有语法错误,但是可能存在错误,比如会导致线程死锁。这些都是错误列表应该检查的。静态检查的可操作方式:

  • 代码走查
    程序员之间可以隔一定的时间抽取代码进行走查。
    走查的时候根据汇总报告,把这些经验汇成列表,作为下次代码走查的依据。
    该方式的特点是,手工、多人讨论、操作简单,但是效率会比较低。
  • 代码扫描
    使用软件对我们的代码进行扫描,查找出潜在的问题。现在有许多商业的工具能够进行扫描,比如Parasoft JTest、Software Analyzer、pclint等工具,往往不同的工具会针对不同的语言。当然也有很多开源的工具。在这里java方面主要推荐Findbugs。Findbugs可以在多个环境中运行,同时也可以编写自己的检测器,功能比较完善。我们平时可以收集自己的或者是别人的开发经验,把它做成检测器来完善Findbugs的检测体系。软件扫描的特点是,机器扫描、效率高,但是不够灵活。

Java静态检查工具对比

参考:http://blog.csdn.net/ml5271169588/article/details/6975701

http://www.cnblogs.com/hyddd/archive/2008/12/16/1356310.html

工具目的检查项
FindBugs 检查.class基于Bug Patterns概念,查找javabytecode(.class文件)中的潜在bug主要检查bytecode中的bug patterns,如NullPoint空指针检查、没有合理关闭资源、字符串相同判断错(==,而不是equals)等
PMD检查源文件检查Java源文件中的潜在问题主要包括:空try/catch/finally/switch语句块;未使用的局部变量、参数和private方法;空if/while语句;过于复杂的表达式,如不必要的if语句等;复杂类
CheckStyle检查源文件主要关注格式检查Java源文件是否与代码规范相符主要包括:Javadoc注释;命名规范;多余没用的Imports;Size度量,如过长的方法;缺少必要的空格Whitespace;重复代码

一、findbugs简介

Findbugs是一个静态分析工具,它检查类或者JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。Findbugs自带检测器,其中有60余种Bad practice,80余种Correctness,1种 Internationalization,12种Malicious code vulnerability,27种Multithreaded correctness,23种Performance,43种Dodgy。我们还可以自己配置检查规则(做哪些检查,不做哪些检查),也可以自己来实现独有的校验规则(用户自定义特定的bug模式需要继承它的接口,编写自己的校验类,属于高级技巧)。

二、使用方法

2.1、Ant工具

Ant是一个很好的Java自动执行工具。

Findbugs官方提供了Ant的findbugs操作方法,我们可以通过这样一个build.xml文件来使用findbugs。

<project name="项目名" default="all">
<property name="findbugs.home" value="findbugs解压路径" />
              <path id="findbugs.path">
                  <fileset dir="findbugs解压路径">
                        <include name="**/*.jar" />
                   </fileset>
              </path>
              <taskdef name="findbugs"
                   classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
                   classpathref="findbugs.path" />
              <!--  定义findbugs的home,findbugs的task要使用  -->
              <target name="findbugs">
                   <findbugs home="${findbugs.home}"
                        output="xml:withMessages" outputFile="生成的文件">
                     
                        <!--  以上定义findbugs查找的类路径  -->
                        <auxClasspath path="${findbugs.home}/lib/findbugs-ant.jar" />
                        <auxClasspath>
                            <fileset dir="lib"
                            includes="*.jar" />
                        </auxClasspath>
                        <sourcePath path="源文件路径" />
                        <class location="生成类路径" />
                   </findbugs>
          </target>
     </project>

设置好Ant的环境后,在命令中使用ant -f build.xml,或者在Eclipse直接运行build.xml文件,运行后生成了一个xml文件,如果你想用Html的格式查看findbugs的结果,可以把output属性设为:html。这样就可以通过Html来查看findbugs的结果了。

2.2 、Findbugs Eclipse插件

Eclipse的Findbugs插件,可以将Findbugs集成到Eclipse中使用。

2.2.1、Findbugs的Eclipse插件安装方法
  1. 在线安装

安装地址:http://findbugs.cs.umd.edu/eclipse

  1. 离线安装

下载Findbugs插件,将它放入Eclipse下的plusin文件夹,然后重启Eclipse

2.2.2、Findbugs的Eclipse插件使用

安装了Findbugs插件后。右击点击你要检查的项目选择【Find Bugs】->【Find Bugs】进行检查。

要查看Findbugs检查出了哪些Bug,可以选择Windows菜单->Show View->Bug Explorer,打开Bug Explorer面板。

如果想要查看某个Bug详细的信息,则可以选择Windows菜单->Open Perspective,然后选择FindBugs就可以打开FindBugs的Properties面板,在这个面板里面可以看到最详尽的Bugs信息。

2.2.3、可以配置的选项的相关设置
1. Run FindBugs Automatically开关
当此项选中后,FindBugs将会在你修改Java类时自动运行,如你设置了Eclipse自动编译开关后,当你修改完Java文件保存,FindBugs就会运行,并将相应的信息显示出来。
当此项没有选中,你只能每次在需要的时候自己去运行FindBugs来检查你的代码。

2. Minimum priority to report选择项
这个选择项是让你选择哪个级别的信息进行显示,有Low、Medium、High三个选择项可以选择,很类似于Log4J的级别设置啦。 比如:
你选择了High选择项,那么只有是High级别的提示信息才会被显示。
你选择了Medium选择项,那么只有是Medium和High级别的提示信息才会被显示。
你选择了Low选择项,那么所有级别的提示信息都会被显示。

3. Enable bug categories选择项
在这里是一些显示Bug分类的选择:
Correctness关于代码正确性相关方面的
Performance关于代码性能相关方面的
Internationalization关于代码国际化相关方面的
Multithreaded correctness关于代码多线程正确性相关方面的
Style关于代码样式相关方面的
Malicious code vulnerability关于恶意破坏代码相关方面的
比如:如果你把Style的检查框去掉不选择中它,那么与Style分类相关的警告信息就不会显示了。其它的类似。

4. Select bug patterns to check for选择项
在这里你可以选择所要进行检查的相关的Bug Pattern条目

可以从Bug codes、Detector name、Detector description中看到相应的是要检查哪些方面的内容,你可以根据需要选择或去掉相应的检查条件。

三、FindBugs错误类型说明

Bad practice 坏的实践,下面列举几个:
	HE:类中equals()hashCode()没有同时定义,或者使用了错误的对象的hashCode()equals()SQLStatement 的execute方法调用了非常量的字符串;或Prepared Statement是由一个非常量的字符串产生。
	DE: 方法终止或不处理异常,一般情况下,异常应该被处理或报告,或被方法抛出。

Correctness 一般的正确性问题,可能导致错误的代码,下面列举几个:
	NP: 空指针被引用;在方法的异常路径里,空指针被引用;方法没有检查参数是否nullnull值产生并被引用;null值产生并在方法的异常路径被引用;传给方法一个声明为@NonNullnull参数;方法的返回值声明为@NonNull实际是nullNm: 类定义了hashcode()方法,但实际上并未覆盖父类ObjecthashCode();类定义了tostring()方法,但实际上并未覆盖父类ObjecttoString();很明显的方法和构造器混淆;方法名容易混淆。
	SQL:方法尝试访问一个Prepared Statement0索引;方法尝试访问一个ResultSet0索引。
	UwF:所有的write都把属性置成null,这样所有的读取都是null,这样这个属性是否有必要存在;或属性从没有被write。

Internationalization 国际化,当对字符串使用upper或lowercase方法,如果是国际的字符串,可能会不恰当的转换。

Malicious code vulnerability 可能受到的恶意攻击,如果代码公开,可能受到恶意攻击的代码,下面列举几个:
	FI: 一个类的finalize()应该是protected,而不是public的。
	MS:属性是可变的数组;属性是可变的Hashtable;属性应该是package protected的。

Multithreaded correctness 多线程的正确性,多线程编程时,可能导致错误的代码,下面列举几个:
	ESync:空的同步块,很难被正确使用。
	MWN:错误使用notify(),可能导致IllegalMonitorStateException异常;或错误的使用wait()No: 使用notify()而不是notifyAll(),只是唤醒一个线程而不是所有等待的线程。
	SC: 构造器调用了Thread.start(),当该类被继承可能会导致错误。

Performance 性能问题,可能导致性能不佳的代码,下面列举几个:
	DM:方法调用了低效的Boolean的构造器,而应该用Boolean.valueOf();用类似Integer.toString(1) 代替new Integer(1).toString();方法调用了低效的float的构造器,应该用静态的valueOf方法。
	SIC:如果一个内部类想在更广泛的地方被引用,它应该声明为staticSS: 如果一个实例属性不被读取,考虑声明为staticUrF:如果一个属性从没有被read,考虑从类中去掉。
	UuF:如果一个属性从没有被使用,考虑从类中去掉。

Dodgy 危险的,具有潜在危险的代码,可能运行期产生错误,下面列举几个:
	CI: 类声明为final但声明了protected的属性。
	DLS:对一个本地变量赋值,但却没有读取该本地变量;本地变量赋值成null,却没有读取该本地变量。
	ICAST: 整型数字相乘结果转化为长整型数字,应该将整型先转化为长整型数字再相乘。
	INT:没必要的整型数字比较,如X <= Integer.MAX_VALUENP: 对readline()的直接引用,而没有判断是否null;对方法调用的直接引用,而方法可能返回nullREC:直接捕获Exception,而实际上可能是RuntimeExceptionST: 从实例方法里直接修改类变量,即static属性。

四、参考文档

1、https://www.jianshu.com/p/af21c21a3451

2、https://www.cnblogs.com/scios/p/5950093.html

3、https://www.cnblogs.com/doit8791/archive/2012/10/22/2734730.html

4、http://testerhome.com/topics/5359

5、https://www.cnblogs.com/simmonner1999/p/5486161.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值