提高代码的质量,除了要提高逻辑上的控制以及业务流程的理解外,代码本身也存在提高的空间,例如一些潜在的问题可以很早的就避免。类似于编码规范上的内容,如果全靠编码人员进行自行检查,那么无疑需要很大的工作量,如果可以使用代码的静态检查工具进行检查的话,那么将大大的提高编码的效率。
本文是提高代码质量系列文章的第二篇,主要介绍了如何使用findbugs工具进行代码的自动化检查,以规避一些潜在的问题并找出代码的逻辑错误。
1. 什么是findbugs?
findbugs是一个程序迎来静态分析java代码中的bug。它是免费软件。FindBugs需要JRE或者JDK5.0或者之后的版本。但是,它可以分析任何java版本编译后的代码。目前FindBugs的版本为1.3.3。更多关于FindBugs的信息,请参考FindBugs主页。
可以在下面的地址
http://findbugs.sourceforge.net/downloads.html
下载FindBugs软件以及eclipse和blueJ的插件。
2. 安装Eclipse的FindBugs插件
作为Java开发的主要开源IDE,Eclipse可以添加FindBugs来提高编写代码的质量,虽然Eclipse中已经包含了一些内置的发现潜在问题(非编译错误,例如warn等警告内容)的方式,但是FindBugs可以找出更多的潜在bugs。
FindBugs插件的更新地址有很多,根据类型的不同,包括以下几个:
http://findbugs.cs.umd.edu/eclipse/:只提供FindBugs的官方释放版本。
http://findbugs.cs.umd.edu/eclipse-candidate/:提供FindBugs的官方释放版本和可选释放版本。
http://findbugs.cs.umd.edu/eclipse-daily:提供最新的FindBugs的插件。除了编译通过外并没有进行测试的版本。
也可以在下面的地址:
http://prdownloads.sourceforge.net/findbugs
下载插件的zip文件,将其解压缩到eclipse的plugin目录(<eclipse_install_dir>/plugins)。
安装完插件后,可以使用Help-->About Eclipse Platform-->Plug-in Details来查看FindBugs插件的使用方法。
3. 在Eclipse中使用FindBugs插件
运行FindBugs插件的方法很简单,选中一个Java工程后,点击右键,选择Find Bugs,这时就会启动FindBugs,并且会在有问题的源代码中显示标记。
可以自定义FindBugs的运行方式:查看Java工程的属性对话框,选择FindBugs的属性页,可以看到如下的选项:
→ 启用/禁用”自动运行FindBugs”复选框---是否在每次修改时进行FindBugs的检查
→ 选择最小的警告优先级,并启用bug的分类---这些选项用于决定显示哪些问题,例如,如果选择Medium警告优先级的话,只有Medium和Hign优先级的警告才会被显示,类似的,如果不选中Style复选框的话,那么有关Style类别的警告也不会被显示。
→ 选择检查引擎:对指定的工程启用那些detectors。
具体的设置画面如下:
(设置detectors和是否自动运行FindBugs)
(设置启用的分类)
4. 在Ant中使用FindBugs
Ant作为一个优秀的自动化构建软件,大量的应用在Java软件开发中(虽然有被Maven取代的危险)。FindBugs提供了集成在Ant中使用的Ant Task,可以在自动构建与部署的时候运行FindBugs。
将$FINDBUGS_HOME/lib/findbugs-ant.jar拷贝到$ANT_HOME/lib目录下以后,就完成了FindBugs的Ant Task的安装。(强烈建议使用FindBugs附带的jar文件)
为了将FindBugs任务集成到Ant脚本中,需要首先进行一个task的定义,如下面的片段所示:
<taskdef name=”findbugs” classname=”edu.umd.cs.findbugs.anttask.FindBugsTask” />
在定义了findbugs task之后,就可以使用了。下面是一个例子:
<property name="findbugs.home" value="/export/home/daveho/work/findbugs" />
<target name="findbugs" depends="jar">
<findbugs home="${findbugs.home}"
output="xml"
outputFile="bcel-fb.xml" >
<auxClasspath path="${basedir}/lib/Regex.jar" />
<sourcePath path="${basedir}/src/java" />
<class location="${basedir}/bin/bcel.jar" />
</findbugs>
</target>
findbugs元素必须有home属性,用于指定FindBugs的安装路径。
这是就会在bcel.jar上执行FindBugs。FindBugs的运行结果会被以xml的格式保存在bcel-fb.xml文件中。一个辅助的jar文件被添加到auxClasspath元素中,因为BCEL库引用了它。
关于findbugs任务的详细说明,如下:
class
嵌套元素指定要分析的类。这个元素必须指定一个location属性,location属性的名字为archive文件(jar,zip等)、目录或者class文件。可以为一个findbugs元素指定多个class元素。
auxClasspath
可选的嵌套元素,用于指定要分析的类所引用的类,但是并不对引用的类进行分析。
sourcePath
可选的嵌套元素,指定Java源代码的目录。
home
必须的属性,findbugs的安装目录。
quietErrors
可选的布尔型属性。如果是true的话,报告严重的分析错误和丢失的类。默认情况下为false。
reportLevel
可选的属性。指定优先级别。如果是low的话,那么报告所有的bug,如果是medium(缺省值),报告medium和high优先级的bug。
output
可选属性,设置输出格式。
stylesheet
可选属性,指定生成html时使用的样式表。
sort
可选属性,如果输出属性设置为text,该属性指定是否对输出结果根据class进行排序,默认为true。
outputFile
可选属性,指定输出文件。
debug
可选的布尔型属性,是否打印分析过程中的日志。默认值为false。
effort
设置分析工作的等级,可以为min、default和max。
conserveSpace
和min effort一样的功能。
workHard
和max effort一样的功能。
visitors
可选属性,指定逗号分隔的列表,指定要运行的detectors。
omitVisitors
可选属性,忽略detectors。折合visitors属性类似,只是不指定不运行哪些detectors。
excludeFilter
可选属性,指定排除的Filter。
includeFilter
可选属性,指定包含的Filter。
projectFile
可选属性,指定项目的名称。
jvmargs
可选属性,指定JVM变量。
systemProperty
系统属性。
timeout
可选属性,指定超市的时间,默认为600,000毫秒,即10分钟。
failOnError
可选属性,指定是否在运行FindBugs出现异常时停止构建过程,默认为false。
errorProperty
可选属性,如果在运行FindBugs时发生错误,指定属性的值为true。
warningsProperty
可选属性,如果在运行FindBugs时发生警告,指定属性的值为true。
5. 命令行下使用FindBugs和图形化的FindBugs的使用
此处不介绍这种使用方式,详细内容参考findbugs manual。
6. FindBugs Bug描述
笔者认为其实最重要的还是FindBugs可以帮助我们找出哪些Bugs。
但是FindBugs的Bug描述是在太多,可以参考: