posts - 11, comments - 10, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          日歷

          <2007年1月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          搜索

          •  

          最新評論

          靜態分析工具及使用總結(三)

          Posted on 2007-01-28 22:46 繁星滿空 閱讀(3033) 評論(0)  編輯  收藏 所屬分類: Java

          靜態分析工具及使用總結(三)

          ?

          這里主要介紹三種開源的工具,PMDCheckStyleFindBugs,著重是在Ant里的調用,據說商業軟件JTest也是著名的代碼分析工具,哈哈,要花錢的沒有用過。

          ?

          FindBugs(http://findbugs.sourceforge.net/)版本1.1.1

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


          用法:
          在圖形界面下使用findbugs,可以新建一個工程,設置類的路徑和源代碼的路徑,
          詳細的文檔請參考官方文檔。
          ?????? 下面主要介紹在Ant里的調用。

          ? 下面是build.xml的相關配置:

          < path? id ="findbugs.path" >
          ???<
          fileset? dir ="${lib.dir}/findbugs-1.1.1" >
          ???????<
          include? name ="**/*.jar" ? />
          ???</
          fileset >
          </
          path >
          <
          taskdef? name ="findbugs" ?classname ="edu.umd.cs.findbugs.anttask.FindBugsTask" ?classpathref ="findbugs.path" />
          <!--
          ?以上定義findbugs的task? -->

          <
          property? name ="findbugs.home" ?value ="${lib.dir}/findbugs-1.1.1" ? />
          <!--
          ?定義findbugs的home,findbugs的task要使用? -->

          ?<
          target? name ="findbugs" >
          ????<
          findbugs? home ="${findbugs.home}" ?includeFilter? =?"${lib.dir}\findbugs-1.1.1\?plugin\filter.xml" ?output ="html" ?outputFile ="d:\test.html" ? >
          ????????<
          class? location ="${class.dir}/classes/?" ? />
          ????????<!--
          ?以上定義findbugs查找的類路徑? -->
          ????????<
          auxClasspath? refid ="classpath" />
          ????????<!--
          ?以上定義上述類所依賴的類路徑? -->
          ????????<
          sourcePath? path ="${src.dir}" ? />
          ????????<!--
          ?以上定義源代碼的路徑? -->
          ????</
          findbugs >
          </
          target >


          ????? 其中的${lib.dir}\findbugs-1.1.1\ plugin\filter.xml配置文件的內容如下:

          使用過濾器我們就可以定義使用哪些bug檢測器和針對哪些類進行檢查,因為一旦 項目比較龐大,
          ????? 那查看冗長的bug報告也是十分痛苦的事情。

          < FindBugsFilter >
          ????
          <!-- ?該類使用所有的bug檢測器? -->
          ????
          < Match? class ="com.foobar.AClass" > ????
          ????
          <!-- ?該類使用bugcode為HE的檢測器? -->
          ????
          < Match? class ="com.foobar.BClass" >
          ????????
          < BugCode? name ="HE" ? />
          ????
          </ Match >
          ????
          <!-- ?該類的AMethod和BMethod方法使用bugcode為HE的檢測器? -->
          ????
          < Match? class ="com.foobar.CClass" >
          ????????
          < Or >
          ????????????
          < Method? name ="AMethod" />
          ????????????
          < Method? name ="BMethod" />
          ????????
          </ Or >
          ????????
          < BugCode? name ="HE" />
          ????
          </ Match >
          ?
          </ FindBugsFilter >

          自帶檢測器的介紹: findbugs 自帶60余種Bad practice80余種Correntness1 Internationalization
          ??? 12Malicious code vulnerability27Multithreaded correntness23Performance43Dodgy


          Bad practice
          壞的實踐

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

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

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

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


          Correctness
          一般的正確性問題

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

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

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

          SQL 方法嘗試訪問一個Prepared Statement0索引;方法嘗試訪問一個ResultSet0索引。

          UwF 所有的write都把屬性置成null,這樣所有的讀取都是null,這樣這個屬性是否有必要存在;或屬性從沒有被write


          Internationalization
          國際化

          當對字符串使用upperlowercase方法,如果是國際的字符串,可能會不恰當的轉換。

          ????
          ???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
          危險的

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

          ??? BC 對抽象集合如ListSet的造型;對具體集合如ArrayListHashSet的造型;

          未檢查或無法保證的造型;

          CI 類聲明為final但聲明了protected的屬性。

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

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

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

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

          REC 直接捕獲Exception,而實際上可能時RuntimeException

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

          ?

          自定義檢測器: findbugs 提供了強大的自定義檢測器的功能,首先我們應該清楚需要

          檢查的案例,findbugs的官方文檔里并沒有詳細的介紹如何自定義,那我們只能直接閱讀它的源碼了,著重閱讀BytecodeScanningDetectorByteCodePatternDetector的子類型,它們可以檢測一般類型的問題。Findbugs利用了Byte Code Engineering Library(即BCELApache上的一個開源項目),以實現其檢測器,所有的字節碼掃描都是基于visitor模式。我們可以參照findbugs自帶的檢測器的類的源碼,去編寫一個自定義的檢測器代碼,編寫完后編譯成類文件,同時我們還需要提供兩個XML文件,Findbugs.xmlmessage.xml,在Findbugs.xml里指定檢測器和實現類,檢測器的縮寫、類型如快速或慢速,而message文件里則包括了該檢測器的描述信息,可能是html的,然后將源文件、類文件和上面兩個XML文件打包成jar文件,放在findbugs homeplugin文件夾下,這樣我們就可以使用自定義檢查器了。

          ?

          參考文檔:

          FindBugs 官方文檔(http://findbugs.sourceforge.net/

          FindBugs ,第 1 部分: 提高代碼質量

          http://www-128.ibm.com/developerworks/cn/java/j-findbug1/

          FindBugs ,第 2 部分: 編寫自定義檢測器

          http://www-128.ibm.com/developerworks/cn/java/j-findbug2/

          代碼靜態分析(http://blog.donews.com/foxgem/archive/2005/04/23/347444.aspx
          主站蜘蛛池模板: 东安县| 彰化县| 古浪县| 曲阳县| 呼和浩特市| 安西县| 南康市| 中西区| 靖安县| 绵竹市| 怀安县| 渝北区| 同江市| 湘潭县| 仲巴县| 榆中县| 太保市| 镇巴县| 客服| 罗山县| 吴忠市| 峨山| 昭平县| 寿光市| 隆德县| 龙岩市| 晋城| 仁寿县| 尚志市| 天柱县| 绥滨县| 尼木县| 鹤壁市| 瓦房店市| 榕江县| 玛纳斯县| 枞阳县| 溧阳市| 定西市| 工布江达县| 乐亭县|