maven javadoc中文亂碼問題和CheckStyle編碼規範檢測
阿新 • • 發佈:2018-12-22
介紹
CheckStyle是SourceForge下的一個專案,提供了一個幫助JAVA開發人員遵守某些編碼規範的工具。它能夠自動化程式碼規範檢查過程,從 而使得開發人員從這項重要,但是枯燥的任務中解脫出來。
CheckStyle預設提供一下主要檢查內容:
•Javadoc註釋
•命名約定
•標題
•Import語句
•體積大小
•空白
•修飾符
•塊
•程式碼問題
•類設計
•混合檢查(包活一些有用的比如非必須的 System.out和printstackTrace)
從上面可以看出,CheckStyle提供了大部分功能都是對於程式碼規範 的檢查,而沒有提供象PMD和Jalopy那麼多的增強程式碼質量和修改程式碼的功能。但是,對於團隊開發,尤其是強調程式碼規範的公司來說,它的功能已經足夠強大。
Eclipse外掛安裝和使用
步驟一:http://sourceforge.net/projects/checkclipse/下載checkstyle的eclipse外掛checkclipse。下載後,將包放入eclipse的plugins資料夾下,然後重啟eclipse。在Windows—>preferences下找到checkclipse。如下圖:
勾選Set Project Dir as Checkjstyle Basedir
步驟二:右鍵選中你要進行checkstyle的專案檔案,選擇“properties”。如下圖:
勾選Enable Checkstyle和Set Project ClassLoader.
然後再Checkstyle Configuraion File中選擇專案中checkstyle的配置檔案。這裡我把配置檔案時放置在專案根目錄下,所以點選右側“Browse”按鈕,在專案根目錄下選擇該檔案。按“OK”按鈕。
這樣整個專案的程式碼將根據配置檔案中設定的原則進行出錯提示.結果如下圖:
由圖可知對不符合程式碼規範的程式碼會有錯誤提示,並且有提示資訊。
Maven外掛安裝和使用
首先,修改要檢查程式碼庫top級的pom.xml檔案,在build部分配置CheckStyle的Maven外掛,以便於下載安裝對應版本的外掛(Maven會自動從其映象庫中下載),方法如下:
- <project>
- ...
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <version>2.3</version>
- </plugin>
- </plugins>
- </build>
- ...
- </project>
maven-checkstyle-plugin的最新版本為2.5,其對應的CheckStyle核心版本為5.0;maven-checkstyle-plugin 2.3對應的CheckStyle核心版本為4.4。檢視外掛的pom檔案,可看到如下內容,其中的版本號就為對應的CheckStyle的版本號。
Java程式碼
- <dependency>
- <groupId>checkstyle</groupId>
- <artifactId>checkstyle</artifactId>
- <version>4.4</version>
- </dependency>
接下來,將自定義的規則配置檔案拷貝到top級目錄,在reporting部分的CheckStyle外掛配置中引用配置。
Java程式碼
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>my_checks.xml</configLocation>
- </configuration>
- </plugin>
- </plugins>
- </reporting>
也可以將配置檔案放在子資料夾下,配置中帶上相對路徑即可。
Java程式碼
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>build-tools/src/main/resources/xx/my_checks.xml</configLocation>
- </configuration>
- </plugin>
- </plugins>
- </reporting>
如果使用外掛自帶的規則檔案,可以作如下配置。maven-checkstyle-plugin外掛自帶的規則有sun_checks.xml、maven_checks.xml等,可檢視外掛包。
Java程式碼
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>config/maven_checks.xml</configLocation>
- </configuration>
- <version>2.3</version>
- </plugin>
- </plugins>
- </reporting>
在reporting部分增加jxr外掛,生成程式碼報告,這樣在CheckStyle報告 中點選問題對應的連結就可以直接看到出錯的程式碼。
Java程式碼
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>my_checks.xml</configLocation>
- </configuration>
- <version>2.3</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jxr-plugin</artifactId>
- </plugin>
- </plugins>
- </reporting>
在build和reporting部分增加javadoc外掛,如果pom檔案中已經配置,則只需作相應修改。charset、encoding、docencoding配置用於解決生成的javadoc檔案中文亂碼問題;aggregate配置為true則javadoc報告會集中顯示所有子模組的javadoc。
Java程式碼
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.4</version>
- <configuration>
- <aggregate>true</aggregate>
- <charset>UTF-8</charset>
- <encoding>UTF-8</encoding>
- <docencoding>UTF-8</docencoding>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>my_checks.xml</configLocation>
- </configuration>
- <version>2.3</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jxr-plugin</artifactId>
- </plugin>
- </plugins>
- </reporting>
在maven外掛中使用 install命令將pom檔案中配置的外掛下載安裝到本地,然後使用checkstyle:checkstyle命令進行檢查並生成報告,執行完畢,各專案目錄下會生成target目錄,target/site/checkstyle.html即為該專案的問題報告。
需要注意的是checkstyle:checkstyle僅生成CheckStyle相關報告,因此不能從報告中直接連結到錯誤程式碼;需要同時生成jxr原始碼,使用site。
如果執行checkstyle:checkstyle或site過程中出現如下錯誤,則應該修改CheckStyle規 則配置檔案,去除其中的中文字元。
Java程式碼
- “[ERROR] BUILD ERROR
- [INFO] ------------------------------------------------------------------------
- [INFO] An error has occurred in Checkstyle report generation.
- Embedded error: Failed during checkstyle configuration
- Invalid byte1 of 1-byte UTF-8 sequence.
- ”
最佳實踐
自定義的checkstyle配置檔案
以下程式碼是自定義的checkstyle配置檔案內容,相關說明都已經用註釋形式寫在檔案中。程式碼如下:
Java程式碼
- <!DOCTYPE module PUBLIC
- "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
- "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
- <module name="Checker">
- <!--
- 重複程式碼的檢查,超過8行就認為重複,UTF-8格式 本檢查一定要放在"TreeWalker"節點前,否則在
- Checkclipse中會無法使用。(在ant下可以)
- -->
- <module name="StrictDuplicateCode">
- <property name="min" value="8" />
- <property name="charset" value="UTF-8" />
- </module>
- <module name="TreeWalker">
- <!-- javadoc的檢查 -->
- <!-- 檢查所有的interface和class -->
- <module name="JavadocType" />
- <!-- 命名方面的檢查,它們都使用了Sun官方定的規則。 -->
- <!-- 區域性的final變數,包括catch中的引數的檢查 -->
- <module name="LocalFinalVariableName" />
- <!-- 區域性的非final型的變數,包括catch中的引數的檢查 -->
- <module name="LocalVariableName" />
- <!-- 包名的檢查(只允許小寫字母) -->
- <module name="PackageName">
- <property name="format" value="^[a-z]+(/.[a-z][a-z0-9]*)*$" />
- </module>
- <!-- 僅僅是static型的變數(不包括staticfinal型)的檢查 -->
- <module name="StaticVariableName" />
- <!-- 型別(Class或Interface)名的檢查 -->
- <module name="TypeName" />
- <!-- 非static型變數的檢查 -->
- <module name="MemberName" />
- <!-- 方法名的檢查 -->
- <module name="MethodName" />
- <!-- 方法的引數名 -->
- <module name="ParameterName " />
- <!-- 常量名的檢查 -->
- <module name="ConstantName" />
- <!-- import方面的檢查 -->
- <!-- import中避免星號"*" -->
- <module name="AvoidStarImport" />
- <!--
- 沒用的import檢查,比如:1.沒有被用到2.重複的3.import java.lang的4.import
- 與該類在同一個package的
- -->
- <module name="UnusedImports" />
- <!-- 長度方面的檢查 -->
- <!-- 檔案長度不超過1500行 -->
- <module name="FileLength">
- <property name="max" value="1500" />
- </module>
- <!-- 每行不超過120個字-->
- <module name="LineLength">
- <property name="max" value="120" />
- </module>
- <!-- 方法不超過30行 -->
- <module name="MethodLength">
- <property name="tokens" value="METHOD_DEF" />
- <property name="max" value="30" />
- </module>
- <!-- 方法的引數個數不超過3個。 並且不對構造方法進行檢查-->
- <module name="ParameterNumber">
- <property name="max" value="3" />
- <property name="tokens" value="METHOD_DEF" />
- </module>
- <!-- 空格檢查 -->
- <!-- 允許方法名後緊跟左邊圓括號"(" -->
- <module name="MethodParamPad" />
- <!-- 在型別轉換時,不允許左圓括號右邊有空格,也不允許與右圓括號左邊有空格 -->
- <module name="TypecastParenPad" />
- <!-- 不允許使用"tab"鍵 -->
- <module name="TabCharacter" />
- <!-- 關鍵字 -->
- <!--
- 每個關鍵字都有正確的出現順序。比如 publicstaticfinal XXX 是對一個常量的宣告。如果使用 static
- publicfinal 就是錯誤的
- -->
- <module name="ModifierOrder" />
- <!-- 多餘的關鍵字 -->
- <module name="RedundantModifier" />
- <!-- 對區域的檢查 -->
- <!-- 不能出現空白區域 -->
- <module name="EmptyBlock" />
- <!-- 所有區域都要使用大括號。 -->
- <module name="NeedBraces" />
- <!-- 多餘的括號 -->
- <module name="AvoidNestedBlocks">
- <property name="allowInSwitchCase" value="true" />
- </module>
- <!-- 編碼方面的檢查 -->
- <!-- 不許出現空語句 -->
- <module name="EmptyStatement" />
- <!-- 每個類都實現了equals()和hashCode() -->
- <module name="EqualsHashCode" />
- <!-- 不許使用switch,"a++"這樣可讀性很差的程式碼 -->
- <module name="IllegalToken" />
- <!-- 不許內部賦值 -->
- <module name="InnerAssignment" />
- <!-- 絕對不能容忍魔法數 -->
- <module name="MagicNumber">
- <property name="tokens" value="NUM_DOUBLE, NUM_INT" />
- </module>
- <!-- 迴圈控制變數不能被修改 -->
- <module name="ModifiedControlVariable" />
- <!-- 多餘的throw -->
- <module name="RedundantThrows" />
- <!-- 不許使用未被簡化的條件表示式 -->
- <module name="SimplifyBooleanExpression" />
- <!-- 不許使用未被簡化的布林返回值 -->
- <module name="SimplifyBooleanReturn" />
- <!-- String的比較不能用!= 和 == -->
- <module name="StringLiteralEquality" />
- <!-- if最多巢狀3層 -->
- <module name="NestedIfDepth">
- <property name="max" value="3" />
- </module>
- <!-- try最多被巢狀2層 -->
- <module name="NestedTryDepth">
- <property name="max" value="2" />
- </module>
- <!-- clone方法必須呼叫了super.clone() -->
- <module name="SuperClone" />
- <!-- finalize 必須呼叫了super.finalize() -->
- <module name="SuperFinalize" />
- <!-- 不能catch java.lang.Exception -->
- <module name="IllegalCatch">
- <property name="illegalClassNames" value="java.lang.Exception" />
- </module>
- <!-- 確保一個類有package宣告 -->
- <module name="PackageDeclaration" />
- <!-- 一個方法中最多有3個return -->
- <module name="ReturnCount">
- <property name="max" value="3" />
- <property name="format" value="^$" />
- </module>
- <!--
- 根據 Sun 編碼規範, class 或 interface 中的順序如下: 1.class 宣告。首先是 public,
- 然後是protected , 然後是 package level (不包括access modifier ) 最後是private .
- (多個class放在一個java檔案中的情況) 2.變數宣告。 首先是 public, 然後是protected然後是 package
- level (不包括access modifier ) 最後是private . (多個class放在一個java檔案中的情況)
- 3.建構函式 4.方法
- -->
- <module name="DeclarationOrder" />
- <!-- 不許對方法的引數賦值 -->
- <module name="ParameterAssignment" />
- <!-- 確保某個class 在被使用時都已經被初始化成預設值(物件是null,數字和字元是0,boolean 變數是false.) -->
- <module name="ExplicitInitialization" />
- <!-- 不許有同樣內容的String -->
- <module name="MultipleStringLiterals" />
- <!-- 同一行不能有多個宣告 -->
- <module name="MultipleVariableDeclarations" />
- <!-- 不必要的圓括號 -->
- <module name="UnnecessaryParentheses" />
- <!-- 各種量度 -->
- <!-- 布林表示式的複雜度,不超過3 -->
- <module name="BooleanExpressionComplexity" />
- <!-- 類資料的抽象耦合,不超過7 -->
- <module name="ClassDataAbstractionCoupling" />
- <!-- 類的分散複雜度,不超過20 -->
- <module name="ClassFanOutComplexity" />
- <!-- 函式的分支複雜度,不超過10 -->
- <module name="CyclomaticComplexity" />
- <!-- NPath複雜度,不超過200 -->
- <module name="NPathComplexity" />
- <!-- 雜項 -->
- <!-- 禁止使用System.out.println -->
- <module name="GenericIllegalRegexp">
- <property name="format" value="System/.out/.println" />
- <property name="ignoreComments" value="true" />
- </module>
- <!-- 不許使用main方法 -->
- <module name="UncommentedMain" />
- <!-- 檢查並確保所有的常量中的L都是大寫的。因為小寫的字母l跟數字1太象了 -->
- <module name="UpperEll" />
- <!-- 檢查陣列型別的定義是String[] args,而不是String args[] -->
- <module name="ArrayTypeStyle" />
- <!--
- 檢查java程式碼的縮排 預設配置:基本縮排 4個空格,新行的大括號:0。新行的case4個空格。
- -->
- <module name="Indentation" />
- </module>
- <!-- 檢查翻譯檔案 -->
- <module name="Translation" />
- </module>
CheckStyle應用的最佳實踐
採用CheckStyle以後,編碼規範的檢查就變得及其簡單,可以作為一項切實可行的實踐加以執行。
一般情況下,在專案小組中引入CheckStyle可以按照下面的步驟進行:
1. 強調Code Review與Code Conventions的重要作用;
2. 介紹CheckStyle;
3. 初步應用CheckStyle:參照CheckStyle附帶的配置檔案,酌情加以剪裁,在專案的Maven配置檔案中,新增CheckStyle任務,可以 單獨執行;
4. 修改、定型CheckStyle的配置檔案:按照基本配置檔案執行一段時間(2~3周),聽取開發人員的反饋意見,修改配置資訊;
5. 作為開發過程的日常實踐,強制執行CheckStyle:穩定CheckStyle的配置資訊,同時將CheckStyle任務作為Build的依賴任務 或者配置SCM(目前,CheckStyle可以與SVN有效整合),使得程式碼在加入系統 之前必須通過檢查。
同時需要指出的是,CheckStyle的有效執行需要依賴的條件:
•IDE Format Code的強大功能:由於CheckStyle本身並沒有提供很強大的Code Format等功能,因此,需要藉助IDE的幫助,從而使得在發生錯誤的時候,可以很容易的進行修復。
IDE格式配置使用介紹
在eclipse中的windowpreferencesjavacode style中可以匯入自定義的java編碼風格檔案。如下圖:
點選“Clean Up”,在右側可以看見一個Import按鈕,匯入自定義的cleanup檔案,點選“OK”即可。左側的“Formatter”也是如法炮製。具體自定義的checkstyle,cleanup,formatter檔案可參考壓縮包檔案中的公司程式碼規範檔案夾。