代码静态检查之findbugs

代码静态检查之findbugs该文章介绍了 Java 静态检查工具 findbugs 的使用方法 包括 Ant 工具和 Eclipse 插件的安装和使用 文章提供了一些相关链接供读者参考

大家好,欢迎来到IT知识分享网。

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

  • 代码走查
    程序员之间可以隔一定的时间抽取代码进行走查。
    走查的时候根据汇总报告,把这些经验汇成列表,作为下次代码走查的依据。
    该方式的特点是,手工、多人讨论、操作简单,但是效率会比较低。


  • 代码扫描
    使用软件对我们的代码进行扫描,查找出潜在的问题。现在有许多商业的工具能够进行扫描,比如Parasoft JTest、Software Analyzer、pclint等工具,往往不同的工具会针对不同的语言。当然也有很多开源的工具。在这里java方面主要推荐Findbugs。Findbugs可以在多个环境中运行,同时也可以编写自己的检测器,功能比较完善。我们平时可以收集自己的或者是别人的开发经验,把它做成检测器来完善Findbugs的检测体系。软件扫描的特点是,机器扫描、效率高,但是不够灵活。

Java静态检查工具对比

参考:http://blog.csdn.net/ml/article/details/

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


免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/117995.html

(0)
上一篇 2025-11-16 16:33
下一篇 2025-11-16 17:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信