Eclipse插件開發之FindBugs插件

Findbugs是一個在java程序中查找bug的程序,它查找bug模式的實例,也就是可能出錯的代碼實例,注意Findbugs是檢查java字節碼,也就是*.class文件。

其實準確的說,它是尋找代碼缺陷的,很多我們寫的不好的地方,可以優化的地方,它都能檢查出來。例如:未關閉的數據庫連接,缺少必要的null check,多餘的 null check,多餘的if後置條件,相同的條件分支,重複的代碼塊,錯誤的使用了"==",建議使用StringBuffer代替字符串連加等等。而且我們還可以自己配置檢查規則(做哪些檢查,不做哪些檢查),也可以自己來實現獨有的校驗規則(用戶自定義特定的bug模式需要繼承它的接口,編寫自己的校驗類,屬於高級技巧)。

一、安裝方法

詳情見:http://findbugs.cs.umd.edu/eclipse

If you have previously installed a version of the FindBugs plugin prior to mid-May, 2006, then you should remove it first. Simply remove the de.tobject.findbugs_0.0.n directory from Eclipse's plugins directory.

To install the FindBugs plugin:

1. In Eclipse, click on Help -> Software Update -> Find and Install...

2. Choose the Search for new features to install option, and click Next.

3. Click New Remote Site.

4. Enter the following:

* Name: FindBugs update site

* URL: one of the following (note: no final slash on the url)

o http://findbugs.cs.umd.edu/eclipse for official releases

o http://findbugs.cs.umd.edu/eclipse-candidate for candidate releases and official releases

o http://findbugs.cs.umd.edu/eclipse-daily for all releases, inculding developmental ones and click OK.

5. "FindBugs update site" should appear under Sites to include in search.

Click the checkbox next to it to select it, and click Finish.

6. You should see FindBugs Feature under Select features to install.

(You may have to click on one or two triangles to make it visible in the tree.)

Select the checkbox next to it and click next.

7. Select the I accept option to accept the license and click Next.

8. Make sure the location is correct where you're installing it. The default (your workspace) should be fine. Click Finish.

9. The plugin is not digitally signed. Go ahead and install it anyway.

二、使用方法

本文主要介紹在Eclipse中使用的情況

FindBugs是一個可以在Java程序中發現Bugs的程序。

它是專門用來尋找處於“Bug Patterns”列表中的代碼的。

Bug Patterns指很有可能是錯誤的代碼的實例。

打開Bug Details視圖

Windows => Show View => Other… => FindBugs => BugDetails

在Package Explorer或Navigator視圖中,選中你的Java項目,右鍵,可以看到“Find Bugs”菜單項,子菜單項裏有“Find Bugs”和“Clear Bug Markers”兩項內容,如下圖所示:

我們建立一個簡單的測試文件Test.java 內容如下:

public class Test 

{

private String[] name;

public String[] getName()

{

return name;

}

public void setName(String[] name)

{

this.name = name;

}

}

我們點中“Find Bugs”,運行時會出現如下進度框:

運行結束後可以在Problems中看到增加了如下的警告信息內容

FindBugs運行後的警告信息內容不僅在Problems視圖中顯示,而且將標記在源代碼標記框中,在源代碼編輯器中我們可以看到警告標識,如下圖:

當光標指向你的警告信息的代碼上面時,就會有相應的錯誤提示信息,與Eclipse本身的錯誤或警告信息提示類似。

選中Problems視圖裏出現的相應問題,就會在代碼編輯器裏切換到相應的代碼上去,方便根據相應的提示信息進行代碼的修改。

在Problems視圖裏,選中相應的問題條目,右鍵,在彈出的菜單中,可以看到“Show Bug Details”,如下圖所示:

點中它,會切換到Bug Details視圖上去,顯示更加詳細的提示信息。

當然,在代碼編輯窗口中,點擊帶有警告提示信息的圖標時,也會自動切換到Bud Details窗口去,查看詳細的警告信息,如下圖所示。

根據這裏詳細的信息,你可以得到FindBugs爲什麼會對你的代碼報警告信息,及相應的處理辦法,根據它的提示,你可以快速方便地進行代碼修改。

根據提示,我們將代碼修改成如下,再運行就不會報有警告信息了。

public class Test 

{

private String[] name;

public String[] getName()

{

String[] temp = name;

return temp;

}

public void setName(String[] name)

{

String[] temp = name;

this.name = temp;

}

}

配置FindBugs

選擇你的項目,右鍵 => Properties => FindBugs =>

可以配置的信息包括如上圖所示的四個選項的相關設置:

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是一個靜態分析工具,它檢查類或者JAR 文件,將字節碼與一組缺陷模式進行對比以發現可能的問題。Findbugs自帶檢測器,其中有60餘種Bad practice,80餘種Correctness,1種 Internationalization,12種Malicious code vulnerability,27種Multithreaded correctness,23種Performance,43種Dodgy。

Bad practice 壞的實踐

一些不好的實踐,下面列舉幾個:

HE: 類定義了equals(),卻沒有hashCode();或類定義了equals(),卻使用

Object.hashCode();或類定義了hashCode(),卻沒有equals();或類定義了hashCode(),卻使用Object.equals();類繼承了equals(),卻使用Object.hashCode()。

SQL:Statement 的execute方法調用了非常量的字符串;或Prepared Statement是由一個非常量的字符串產生。

DE: 方法終止或不處理異常,一般情況下,異常應該被處理或報告,或被方法拋出。

Correctness 一般的正確性問題

可能導致錯誤的代碼,下面列舉幾個:

NP: 空指針被引用;在方法的異常路徑裏,空指針被引用;方法沒有檢查參數是否null;null值產生並被引用;null值產生並在方法的異常路徑被引用;傳給方法一個聲明爲@NonNull的null參數;方法的返回值聲明爲@NonNull實際是null。

Nm: 類定義了hashcode()方法,但實際上並未覆蓋父類Object的hashCode();類定義了tostring()方法,但實際上並未覆蓋父類Object的toString();很明顯的方法和構造器混淆;方法名容易混淆。

SQL:方法嘗試訪問一個Prepared Statement的0索引;方法嘗試訪問一個ResultSet的0索引。

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:如果一個內部類想在更廣泛的地方被引用,它應該聲明爲static。

SS: 如果一個實例屬性不被讀取,考慮聲明爲static。

UrF:如果一個屬性從沒有被read,考慮從類中去掉。

UuF:如果一個屬性從沒有被使用,考慮從類中去掉。

Dodgy 危險的

具有潛在危險的代碼,可能運行期產生錯誤,下面列舉幾個:

CI: 類聲明爲final但聲明瞭protected的屬性。

DLS:對一個本地變量賦值,但卻沒有讀取該本地變量;本地變量賦值成null,卻沒有讀取該本地變量。

ICAST: 整型數字相乘結果轉化爲長整型數字,應該將整型先轉化爲長整型數字再相乘。

INT:沒必要的整型數字比較,如X <= Integer.MAX_VALUE。

NP: 對readline()的直接引用,而沒有判斷是否null;對方法調用的直接引用,而方法可能返回null。

REC:直接捕獲Exception,而實際上可能是RuntimeException。

ST: 從實例方法裏直接修改類變量,即static屬性。

總結

此插件的功能很不錯,可以幫助我們提升Java代碼的編寫能力,寫出更加安全可靠的代碼。建議使用或加在Ant裏進行持續構建。

現在,你可以馬上拿出你已經開發的一個項目,檢查一下你的代碼有沒有問題了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章