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

          靜態(tài)分析工具及使用總結(jié)(一)

          Posted on 2006-11-09 17:21 繁星滿空 閱讀(3177) 評論(0)  編輯  收藏 所屬分類: Java

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

          ?

          PMD http://pmd.sourceforge.net/

          簡介: PMD 掃描java源代碼,查找潛在的問題,如:

          可能的bugs,如空的try/catch/finally/switch聲明

          死亡的代碼,沒有使用的本地變量,參數(shù)和私有方法

          不合標準的代碼,如String/StringBuffer用法

          過于復(fù)雜的表達式,如不必要的if表達式

          重復(fù)的代碼,拷貝、粘貼的代碼

          PMD 的含義,如

          Project Mess Detector

          Project Monitoring Directives

          Project Meets Deadline

          Programming Mistake Detector…

          ?

          用法: 可以在命令行下執(zhí)行,如

          pmd c:\Test.java xml rulesets/unusedcode.xml

          也可以使用IDE的插件,如EclipseIDEAJBuilderJCreator等等

          這里主要介紹Ant里的調(diào)用,

          下面是主要的Ant配置信息
          <path?id="pmd.path">????
          ????
          <fileset?dir="${lib.dir}/pmd-3.8">
          ????????
          <include?name="**/*.jar"?/>
          ????
          </fileset>
          </path>
          <taskdef?name="pmd"?classname="net.sourceforge.pmd.ant.PMDTask"?classpathref="pmd.path"/>
          <taskdef?name="cpd"?classname="net.sourceforge.pmd.cpd.CPDTask"?classpathref="pmd.path"/>
          ????
          <target?name="pmd">
          ????????
          <pmd?shortFilenames="true">
          ????????????
          <ruleset>rulesets/favorites.xml</ruleset>????????????
          ????????????
          <formatter?type="html"?toFile="d:\foo.html"?toConsole="false"/>
          ????????????
          <fileset?dir="${src.dir}">
          ????????????????
          <include?name="**/*.java"/>
          ????????????
          </fileset>
          ????????
          </pmd>
          ????
          </target>
          <target?name="cpd">????????
          ????????
          <cpd?minimumTokenCount="100"?outputFile="d:/cpd.txt">
          ????????????
          <fileset?dir="${src.dir}">
          ????????????????
          <include?name="**/*.java"/>
          ????????????
          </fileset>
          ????????
          </cpd>
          ????
          </target>

          自定義規(guī)則:

          有兩個辦法來自定義規(guī)則,可以編寫java類和編寫XPath,編寫java類的一般步驟是,先確定要查找的代碼形式,利用PMD自帶的designer.bat工具查看AST(抽象語法樹),然后編寫規(guī)則類(繼承net.sourceforge.pmd.AbstractRule),然后編寫一個rulesetXML文件,最后就可以運行PMD進行檢查。編寫XPath比編寫java類要容易些,但也需要掌握AST的含義,利用designer.bat工具可以查看AST,比如 //ClassBody [count(//VariableDeclarator[../Type/Name[@Image='Logger']])>1] ,這個表達式就是查找類的代碼里是否聲明了多個 Logger ,然后編寫一個 ruleset XML 文件,最后運行 PMD 進行檢查。這里是一個 ruleset XML 文件的例子。

          ?

          自定義規(guī)則集合:

          PMD 自帶了很多代碼規(guī)范的規(guī)則,還可以自定義規(guī)則,我們可以把這些規(guī)則整合到一起,按照我們的需求進行代碼檢查。
          <!--?使用整個strings規(guī)則集?-->
          ??
          <rule?ref="rulesets/strings.xml"/>
          <!--?使用某個規(guī)則集里的某個規(guī)則?-->
          ??
          <rule?ref="rulesets/unusedcode.xml/UnusedLocalVariable"/>
          ??
          <!--?指定某個規(guī)則集里的某個規(guī)則的優(yōu)先級?-->
          <rule?ref="rulesets/basic.xml/EmptyCatchBlock"?message="Must?handle?exceptions">
          ????
          <priority>2</priority>
          ????
          </rule>
          ??????????
          <!--?去除某個規(guī)則集里的某個規(guī)則?-->
          <rule?ref="rulesets/braces.xml">
          ????
          <exclude?name="WhileLoopsMustUseBracesRule"/>
          ??
          </rule>

          最后,我們運行PMD的時候就可以指定這個 ruleset 文件。

          ?

          自帶規(guī)則的介紹:

          PMD 自帶了很多規(guī)則集合,并且分類寫入不同的 ruleset 文件,如

          Basic 包含每人都必須遵守的代碼最佳實踐,如EmptyCatchBlock

          Braces 關(guān)于條件分支的規(guī)則,如IfStmtsMustUseBraces

          Code Size 關(guān)于代碼大小的規(guī)則,如方法的長度,參數(shù)的長度,屬性的個數(shù)等

          Clone 克隆實現(xiàn)的規(guī)則,如是否有super.clone()

          Controversial 一些有爭議的規(guī)則,如UnnecessaryConstructor不必要的構(gòu)造器

          Coupling 對象連接有關(guān)的規(guī)則

          Design 可以檢查有問題的設(shè)計,如SwitchStmtsShouldHaveDefault

          Finalizers 使用finalizers時需遵循的規(guī)則,如FinalizeOnlyCallsSuperFinalize

          Import Statements import有關(guān)的規(guī)則,如DuplicateImports重復(fù)import

          J2EE 唯一規(guī)則UseProperClassLoaderclass.getClassLoader()可能不正確,用

          Thread.currentThread().getContextClassLoader() 代替

          Javabeans javabean規(guī)范有關(guān)的規(guī)則,有BeanMembersShouldSerialize屬性必須

          序列化和MissingSerialVersionUID缺少序列化ID

          JUnit Tests JUnit測試有關(guān)的,如JUnitSpelling拼寫檢查等

          Logging (Java) 檢查Logger的一些錯誤用法,如MoreThanOneLogger多個Logger

          Logging (Jakarta) 使用Jakarta Logger的一些規(guī)則,有UseCorrectExceptionLogging

          異常處理不當和ProperLogger是否正確定義Logger

          Migrating JDK 版本移植的規(guī)則,如ReplaceVectorWithListList代替Vector

          Naming 和命名有關(guān)的規(guī)則,名稱太短或太長,命名的約定等

          Optimizations 優(yōu)化性能的一些規(guī)則,如LocalVariableCouldBeFinal本地變量如果

          只賦值一次,則應(yīng)該聲明為final

          Strict Exceptions 比較嚴格的異常處理方針,如AvoidCatchingThrowable

          Strings 使用StringStringBuffer時應(yīng)遵守的規(guī)則,如StringToString

          Sun Security 編寫安全的代碼,有MethodReturnsInternalArray直接返回內(nèi)部的數(shù)組,

          更安全的做法是返回一個拷貝和ArrayIsStoredDirectly

          Unused Code 檢查未使用的代碼,如UnusedPrivateField未使用的私有屬性

          Java Server Pages 編寫jsp的一些方針,如NoLongScripts

          Java Server Faces 編寫jsf的一些方針,有DontNestJsfInJstlIteration,在Jsf

          里使用jstl的標簽

          PMD 里面還有一個寫好的ruleset文件,在pmd-3.8.jar里面的rulesets文件夾下,名稱是favorites.xml,以下是主要部分:

          < rule? ref ="rulesets/basic.xml" />
          < rule? ref ="rulesets/basic.xml/EmptyCatchBlock" ?message ="Must?handle?exceptions" >
          ????????
          < priority > 2 </ priority >
          </ rule >
          ????
          < rule? ref ="rulesets/unusedcode.xml" />
          < rule? ref ="rulesets/braces.xml/WhileLoopsMustUseBraces" />
          < rule? ref ="rulesets/braces.xml/ForLoopsMustUseBraces" />
          < rule? ref ="rulesets/design.xml/SimplifyBooleanReturns" />
          < rule? ref ="rulesets/design.xml/SwitchStmtsShouldHaveDefault" />
          < rule? ref ="rulesets/strings.xml/StringToString" />
          < rule? ref ="rulesets/strings.xml/StringInstantiation" />
          < rule? ref ="rulesets/controversial.xml/UnnecessaryConstructor" />
          < rule? ref ="rulesets/controversial.xml/NullAssignment" />
          < rule? ref ="rulesets/controversial.xml/UnusedModifier" />
          < rule? ref ="rulesets/codesize.xml/CyclomaticComplexity" >
          ????
          < properties >< property? name ="reportLevel" ?value ="5" /></ properties >
          </ rule >

          其它事項:

          1.???? 可以使用JDK1.5的聲明 @SuppressWarnings(""),禁止PMD的警告。

          2.???? 可以使用//NOPMD來標記行或塊代碼,禁止PMD警告。

          3.???? 有兩種方法自定義Rule,編寫java類和編寫XPath

          4.???? PMD 提供了多種IDE的插件來運行PMD

          ?

          ?

          ?

          參考文檔:

          PMD 官方文檔(http://pmd.sourceforge.net/

          OnJava 上一篇文檔( http://www.onjava.com/pub/a/onjava/2003/04/09/pmd_rules.html

          代碼靜態(tài)分析(http://blog.donews.com/foxgem/archive/2005/04/23/347444.aspx

          ?

          主站蜘蛛池模板: 西华县| 南投市| 漳平市| 潮州市| 资溪县| 宜昌市| 宁河县| 松滋市| 江孜县| 阿荣旗| 顺昌县| 蕉岭县| 牟定县| 博乐市| 深水埗区| 平远县| 荣昌县| 女性| 额济纳旗| 锡林郭勒盟| 广饶县| 宣城市| 密山市| 原平市| 邳州市| 台湾省| 广河县| 苏尼特左旗| 广宗县| 大姚县| 友谊县| 类乌齐县| 巨鹿县| 新乡市| 祁连县| 汉沽区| 嵊州市| 夏邑县| 郴州市| 莎车县| 二连浩特市|