Error-prone,Google出品的Java和Android Bug分析利器
是什么
- 靜態的Java和Android bug分析利器
- 由Google出品
- 由error-prone接管compiler,在代碼編譯時進行檢查,并拋出錯誤中斷執行
- 在拋出錯誤的同時給出具體的原因和相應方案
- error-prone github 地址為 https://github.com/google/error-prone
舉幾個例子
private void testCollectionIncompatibleType() {
Set<Short> set = new HashSet<>();
set.add(Short.valueOf("1"));
set.remove(0);
}
上面的代碼中
- set是一個接受Short類型的集合
- 我們想通過類似從List.remove(index)方式刪除一個元素
- 但是Set沒有remove(index)方法,有的只是remove(Object)方法,普通編譯器不會報錯,而error-prone則會發現
報出的錯誤信息為
/Users/jishuxiaoheiwu/github/ErrorProneSample/app/src/main/java/com/example/jishuxiaoheiwu/errorpronesample/MainActivity.java:24:
error: [CollectionIncompatibleType] Argument '0' should not be passed to this method; its type int is not compatible with its collection's type argument Short
set.remove(0);
^
(see http://errorprone.info/bugpattern/CollectionIncompatibleType)
再舉一個例子
"hello World".getBytes().toString();
報出的錯誤是
/Users/jishuxiaoheiwu/github/ErrorProneSample/app/src/main/java/com/example/jishuxiaoheiwu/errorpronesample/MainActivity.java:16:
error: [ArrayToString] Calling toString on an array does not provide useful information
"hello World".getBytes().toString();
^
(see http://errorprone.info/bugpattern/ArrayToString)
提示上面的byte[].toString()方法打印沒有有用信息。
BugPattern
Error-prone是基于BugPattern來發現問題的,覆蓋范圍不僅限于Java還包含Android代碼。一些比較常見的BugPattern有如下這些
- ArrayToString 直接調用數組的toString方法打印不出有用信息
- DivZero 0不能做除數,即分母
- DefaultCharset 調用系統默認的Charset
- MissingDefault switch中缺少default
- MislabeledAndroidString Android中的字符串命名和內容不匹配,具有誤導性
- HardCodedSdCardPath 硬編碼sd卡路徑
- IsLoggableTagLength log tag字符數量過長
- 其他
- 更多的bug pattern請參考 bugpatterns
BugPattern有三種嚴重程度,如下
- ERROR
- WARNING
- SUGGESTION
只有ERROR的嚴重程度才會中斷當前的編譯,其他情況都會以日志輸出形式展現。
如何配置
error-prone有對應的gradle插件,只需要應用即可。需要的操作很簡單,只需要三步
- 增加相應的maven repo
- 在依賴中設置error-prone plugin classpath
- 應用error-prone plugin
一個完整的代碼示例如下,修改的文件為Project的build.gradle文件
buildscript {
repositories {
jcenter()
// error-prone相關配置
maven {
url "
allprojects {
repositories {
jcenter()
}
//error-prone相關配置
apply plugin: "net.ltgt.errorprone"
}
</code></pre>
- 具體參考 net.ltgt.errorprone
- 其他配置方法 Maven, Ant等
開啟/關閉部分檢查
Error-prone plugin提供了方法允許我們配置bugpattern的處理方式。
基本的做法是
tasks.withType(JavaCompile) {
options.compilerArgs += [ '-Xep:<checkName>[:severity]' ]
}
比如我們想要將ArrayToString從ERROR轉成WARNING,我們可以這樣做
tasks.withType(JavaCompile) {
options.compilerArgs += [ '-Xep:ArrayToString:WARN' ]
}
除此之外還有一些特殊的參數
- -XepAllErrorsAsWarnings 將全部的Error轉成WARNING
- -XepAllDisabledChecksAsWarnings 開啟全部的check,之前禁止的作為WARNING級別處理
- -XepDisableAllChecks 關閉所有的check
分條件開啟error-prone插件
理論上,error-prone在編譯時期進行代碼分析并檢查,會延長了編譯時間,加之Gradle編譯本來就很慢,為了不對我們日常的構建造成影響,我們可以分條件開啟error-prone,即
- 在日常開發構建,禁止應用error-prone插件,不對構建時間影響
- 在特殊場景,比如持續集成時應用error-prone插件,用來發現問題。
具體的做法是通過想gradle傳遞參數來實現。簡易代碼如下。
allprojects {
repositories {
jcenter()
}
//如果接受的參數有enableErrorProne則應用插件,否則不應用
if (project.hasProperty("enableErrorProne")) {
apply plugin: "net.ltgt.errorprone"
}
}
使用如下,則會開啟應用插件
./gradlew assembleDebug -PenableErrorProne
注意
- 由于是靜態分析工具,即使問題代碼不被執行也會檢測出來。
- 一次編譯過程中,error-prone可以報出多個錯誤
- Android Studio也有對應的error-prone插件,大家也可以使用。
以上就是關于error-prone的一些簡單總結。Error-prone在Flipboard中已經應用很久,采用的方式為開發構建時不開啟,在持續集成時開啟。大家可根據自己和團隊的需要選擇并應用error-prone,來快速發現問題并改善代碼的質量。
來自:http://droidyue.com/blog/2017/04/09/error-prone-tool-for-java-and-android/