【工利其器】必會工具之(八)PMD篇——程式碼分析工具基本使用
- 2019 年 11 月 10 日
- 筆記
如今,使用程式碼分析工具來代替人工進行程式碼審查,已經是大勢所趨了。用於Java程式碼檢測的工具中,不乏許許多多的佼佼者,其中PMD就是其中一款。PMD既可以獨立運行,也可以以命令行的形式運行,還可以作為插件在IDE中運行,本文將基於在Android Studio中的使用來介紹PMD的基本使用。
一、PMD簡介
對於PMD名稱含義,有個有趣的現象,PMD不存在一個準確的名稱,在官網上你可以發現很有有趣的名稱 ,比如:Pretty Much Done,Project Meets Deadline等。PMD是一款程式程式碼檢查工具(可以支援多種語言,以Java為例),通過靜態分析Java源文件來獲知程式碼錯誤,也就是說在不運行不編譯Java程式的情況下直接掃描Java源文件,報告錯誤 。該軟體功能強大,掃描效率高,是Java程式設計師debug的好幫手。它附帶了許多可以直接使用的規則,利用這些規則可以找出Java源程式的許多問題,比如:
- 可能的 Bugs:檢查潛在程式碼錯誤,如空 try/catch/finally/switch 語句
- 未使用程式碼(Dead code):檢查未使用的變數,參數,方法
- 複雜的表達式:檢查不必要的 if 語句,可被 while 替代的 for 循環
- 重複的程式碼:檢查重複的程式碼
- 循環體創建新對象:檢查在循環體內實例化新對象
- 資源關閉:檢查 Connect,Result,Statement 等資源使用之後是否被關閉掉
用戶還可以自己定義規則,檢查Java程式碼是否符合某些特定的編碼規範。例如,你可以編寫一個規則,要求PMD找出所有創建Thread對象的操作。
PMD支援的編輯器包括:JDeveloper、Eclipse、JEdit、JBuilder、BlueJ、CodeGuide、NetBeans/Sun Java Studio Enterprise/Creator、IntelliJ IDEA(Android Studio是基於此編輯器)、TextPad、Maven、Ant、Gel、JCreator和Emacs。
二、PMD的安裝
通過File > Settings > Plugins > Browse repositories 搜索 “PMD”,找到“PMDPlugin”這一項,按照提示進行安裝,然後重啟即可。
三、使用PMD檢測程式碼
1、啟動PMD檢測功能
(1)從Tools菜單中啟動
通過Tools > Run PMD可以看到如下的介面。從運行結果來看,如果通過該方式啟動,掃描的範圍就是整個個項目中的文件了。
Pre Defined:表示預定義的規則,也就是該插件自帶的檢測規則。後面展開的列表中列處了所有的規則列表,想掃描哪一種類型的問題,點擊即可。其中“All”表示使用所有的規則。
Custom Rules:自定的檢測規則。該插件允許用戶根據自己的需要自定義檢查規則,默認這裡是不可點擊的,需要在設置中導入自定義規則文件後方可選擇。
(2)從右鍵菜單中啟動
在文件或者編輯器中點擊右鍵,也可以看到“Run PMD”選項,和從“Tools”菜單中啟動一樣,這裡不贅述了。通過該方式啟動, 檢測範圍取決於滑鼠或游標當前所選中的區域。
2、運行結果
運行後會出現如下面板:
左邊工具欄,滑鼠停留在上面會提示其功能,比較簡單就不啰嗦了。右邊顯示了檢測結果,這裡顯示的結果類別取決於我們運行的時候在“Pre Defined”中選擇的規則類型,因為前面選擇的“All”,所以所有的規則都顯示了。當點擊具體某一問題項時,會跳轉到對應的源碼中。
四、配置檢測規則
通過File > Settings > Other Settings > PMD可以打開檢測規則的設置介面:
在“RuleSets(規則設置)”介面可以管理自定義的檢測規則。因為在實際工作中,可能有些團隊需要根據實際情況自定義檢測規則,就可以通過這裡導入。如果要使用它,需要在啟動PMD進行檢測時選擇該自定義規則。
點擊“Options”選項卡,在其中可以配置一些檢測規則選項
其中重點需要留意的是“Skip TestSource”這一項,因為在項目中有不少Android Studio自動生成的測試程式碼,如下所示,選擇上述選項後可以將其過濾掉。
五、PMD的高級使用
本文主要介紹PMD的基本使用,同時限於筆者的水平有限,這裡僅簡單介紹一下它的高級使用。
PMD功能非常強大,僅僅是針對Java的檢測就附帶了讓人眾多的規則,這裡提供一份《PMD插件分析程式碼規則(中文).xls》文檔,有興趣的可以下載深入了解:
鏈接:https://pan.baidu.com/s/189OTD_k-RbEX4ABJbAMlIg
提取碼:90f4
對於自定義規則,這裡提供一個自定義模板(pmd_custom_rule.xml,可以直接導入使用),可以通過這個模板學習一下PMD的規則定義:
1 <?xml version="1.0"?> 2 <ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Android Application Rules" 3 xmlns="http://pmd.sf.net/ruleset/1.0.0" 4 xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd" 5 xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"> 6 7 <description>Custom ruleset for ribot Android application</description> 8 9 <exclude-pattern>.*/R.java</exclude-pattern> 10 <exclude-pattern>.*/gen/.*</exclude-pattern> 11 12 <rule ref="rulesets/java/android.xml" /> 13 <rule ref="rulesets/java/clone.xml" /> 14 <rule ref="rulesets/java/finalizers.xml" /> 15 <rule ref="rulesets/java/imports.xml"> 16 <!-- Espresso is designed this way !--> 17 <exclude name="TooManyStaticImports" /> 18 </rule> 19 <rule ref="rulesets/java/logging-java.xml"> 20 <!-- This rule wasn't working properly and given errors in every var call info --> 21 <exclude name="GuardLogStatementJavaUtil" /> 22 </rule> 23 <rule ref="rulesets/java/braces.xml"> 24 <!-- We allow single line if's without braces --> 25 <exclude name="IfStmtsMustUseBraces" /> 26 </rule> 27 <rule ref="rulesets/java/strings.xml" > 28 <!-- Exclude because causes problems with SQL Strings that usually require duplication --> 29 <exclude name="AvoidDuplicateLiterals"/> 30 </rule> 31 <rule ref="rulesets/java/basic.xml" /> 32 <rule ref="rulesets/java/naming.xml"> 33 <exclude name="AbstractNaming" /> 34 <exclude name="LongVariable" /> 35 <exclude name="ShortMethodName" /> 36 <exclude name="ShortVariable" /> 37 <exclude name="ShortClassName" /> 38 <exclude name="VariableNamingConventions" /> 39 </rule> 40 </ruleset>
友情鏈接:
PMD Java rules官方文檔介紹:https://pmd.github.io/pmd-6.19.0/pmd_rules_java.html
PMD 官網:https://pmd.github.io