提高代碼的質量,除了要提高邏輯上的控制以及業務流程的理解外,代碼本身也存在提高的空間,例如一些潛在的問題可以很早的就避免。類似於編碼規範上的內容,如果全靠編碼人員進行自行檢查,那麼無疑需要很大的工作量,如果可以使用代碼的靜態檢查工具進行檢查的話,那麼將大大的提高編碼的效率。
本文是提高代碼質量系列文章的第二篇,主要介紹瞭如何使用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描述是在太多,可以參考: