引言
在 Java 软件开发过程中,开发团队需要花费大量时间精力在发现并修改代码缺陷上。 静态代码分析( static code analysis ) 工具能够在代码构建过程中帮助开发人员快速、有效地定位代码缺陷并及时纠正代码问题,从而极大提高软件可靠性且节省了开发成本和测试成本。现在市场上有很多静态分析工具,选择太多以至于难以确定要引入哪种工具,最近组里正好要在项目内引入静态代码分析,花了些时间对现有几种工具进行调研,本文将分别介绍现有四种主流 Android 静态代码分析工具(Checkstyle、Spotbugs、PMD、Infer),并从功能、特性、自定义等方面对它们进行分析和比较,希望能够供各位选择时提供一些参考。
静态代码分析工具简介
什么是静态代码分析
静态代码分析是指在无需执行程序的情况下即可进行的针对代码正确性、合规性的分析。分析主要分为几种层级:针对源码级别的分析、针对中间代码的分析、针对编译后字节码的分析。静态分析可作为项目构建的一部分,可选择在构建之后生成问题报告,严谨点可以选择在检测到严重问题时中止构建过程,等待开发人员修复问题后重新构建。
较为关注的分析类型
- 潜在bug检测 (空指针,内存泄漏,线程安全等)
- 团队代码风格统一
- 代码设计缺陷检测
- 无用、重复代码查找
其他优势
静态代码分析的优势还在于检测速度,由于无须运行(甚至某些检测工具无须编译项目代码),所以检测速度飞快.
分析正文
Checkstyle
主要目的
检测 Java 代码风格是否符合预定编码规则
分析层级
项目分析仅限于语法层面,不需要其他预处理,只会根据代码生成简单抽象语法树(AST
)
检测方面
专注于 Java
代码风格方面的检测(无用代码检测,命名、空格、format、代码约定检测,以及过于复杂的表达式等)。对于其他方面比如 bug 的检测算是比较鸡肋,能检测部分有 String.equals 检测的空指针,几种代码设计方面的检测,具体检测类型可见: Class Design
自定义
Checkstyle 普通自定义是建立在现有提供的规则上通过 XML 修改、启用具体规则,简单直观。具体官方的支持检测类型:Checkes.
提供几种参考配置:
如果对现有提供的规则不满意,还可以开发自己的检查规则,检查规则通过 Java 开发,需要了解 Checkstyle 生成的简单 AST,Checkstyle 提供有工具将欲检查的 Java 代码转换为对应的 AST.
具体开发教程:
[Write Custom Rules] (checkstyle.sourceforge.net/writingchec…)
PMD
主要目的
识别代码潜在问题
分析层级
PMD 分析由源码通过 JavaCC 生成的 AST,不要求预先编译
检测方面
PMD 的检测比较全面,不仅能够识别潜在 bug ,还能够检测代码风格方面的问题。
而 PMD 缺点在于其检测仅基于单个文件,整个分析不是针对项目。PMD 对 Java 的检测类型可以观看:PMD Java Rulesets。
PMD 对很多主流 IDE、编辑器如 Eclipse、Intellij IDEA、Emacs 等有插件支持,
具体列表见:IDE plugin list
自定义
基础配置也比较简单,和 Checkstyle 相同可以通过 xml 进行简单自定义配置。
自定义规则可以选择通过 Java
或 XPath
表达式来开发,主要通过分析对应的 AST 结构,找出相符合的规律进行判断。 PMD 有提供 GUI 工具将想检测的代码生成对应 AST,相对来说开发难度不高。
官方自定义规则开发教程:
Write a PMD Rule
Spotbugs(原 Findbugs)
主要目的
识别代码潜在问题
分析层级
Spotbugs 分析编译后的字节码,要求预先编译
检测方面
Spotbugs 专注于 Java
代码的 bug 检测,能够检测多线程、空指针等问题,以及代码设计方面的一些缺陷和一些不好的实现,对于代码的分析不仅仅局限于当前检测的类,在 java 这方面相对来说代码的检测比较全面、准确性更高。因而在这四种工具中,Spotbugs 在检测 bug 方面个人认为是个较好的选择。
Spotbugs 还有很多基于各种 IDE 的插件,笔者在 Android Studio 上面的体验相对来说很不错,对于错误、可能引起的问题说明、修改建议的展示都很直观。
自定义
Spotbugs 的自定义探测器 (Detector) 和 Findbugs 相同,使用 Java 语言开发。开发需要对字节码有一定的了解,因为 Spotbugs 的分析是对字节码的分析,难度相对会高一些,维护成本相应会有所增加,好消息是目前 Spotbugs 已经包含了很多常见的 bug patterns,需要自己开发的地方不会太多。
自定义开发教程:
Implement SpotBugs plugin
Infer
主要目的
识别代码潜在问题
分析层级
分析的是源码经过 Infer 转换成的内部中间代码(转换类似编译),因此 Infer 要求检测前先 Clean 工程
检测方面
项目由 Facebook 开源维护,专注于手机端应用的代码质量分析(Android,iOS),目前完善度不高,仅能检测有限的几种问题,对 Android Java 代码来说,包括:Context 泄漏、空指针异常、资源泄漏、多线程资源竞争。
优点在于使用方便,对 ci 支持以及分析流程的可定制程度较高(可以对 git diff 的文件进行分析,可进行增量分析)以及有对 Android 的相对性检测,可以关注下其发展。
自定义
Infer 整个项目是用函数式语言 OCaml
编写的,分析的是源代码转化后的 Infer 内部中间语言。好在 Infer 另外提供了一门声明式语言 Infer:AL
以供用户自定义规则,这使得使用者不需要关注 Infer 的内部实现,但是还是需要关注其生成的 AST 结构,难度较高一些。
官方开发教程:
Infer:AL
最后
以上即为笔者对四种静态代码分析工具的分析,受限于能力学识,如有错误疏漏欢迎交流指正.
参考资料
continuousdev.com/2015/08/che…
spotbugs.readthedocs.io/en/latest/i…
pmd.github.io/pmd-5.8.1/
checkstyle.sourceforge.net/
fbinfer.com/docs/gettin…
www.ibm.com/developerwo…