本文以CentOS作業系統為例介紹Sonar的安裝配置,以及如何與Jenkins進行內建,通過pmd-cpd、checkstyle、findbugs等工具對代碼進行持續審查。
一、安裝配置sonar
1、Sonar介紹
Sonar是一個用于代碼品質管理的開源平台,用于管理Java源代碼的品質。通過插件機制,Sonar 可以內建不同的測試工具,代碼分析工具,以及持續內建工具,比如pmd-cpd、checkstyle、findbugs、Jenkins。通過不同的插件對這些結果進行再加工處理,通過量化的方式度量代碼品質的變化,進而可以友善地對不同規模和種類的工程進行代碼品質管理。
同時 Sonar 還對大量的持續內建工具提供了接口支援,可以很友善地在持續內建中使用 Sonar。
此外,Sonar 的插件還可以對 Java 以外的其他程式設計語言提供支援,對國際化以及報告文檔化也有良好的支援。
2、配置資料庫
Apache Derby 是Sonar自帶并且預設安裝使用的資料庫,此外Sonar對如下資料庫提供支援:MySQL 5.x, Oracle 10g XE, Postgresql, MS SqlServer等,本文以mysql為例介紹如何配置資料庫:
1)建立資料庫
在mysql中執行如下腳本建立資料庫及mysql使用者
CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'sonar' IDENTIFIED BY 'sonar';
GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar';
GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar';
FLUSH PRIVILEGES;
2)編輯${SONAR_HOME}/conf/sonar.properties配置資料庫:
sonar.jdbc.username: sonar
sonar.jdbc.password: sonar
sonar.jdbc.url: jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true
# Optional properties
sonar.jdbc.driverClassName: com.mysql.jdbc.Driver
3)配置DB驅動包
如果使用Oracle資料庫,必須手動複制驅動類到${SONAR_HOME}/extensions/jdbc-driver/oracle/目錄下。其它支援的資料庫預設提供了驅動,http://docs.codehaus.org/display/SONAR/Analysis+Parameters 列舉了一些常用的配置及預設值.
4)常見錯誤及解決方法
添加語言包後,啟動報錯分析:
下載下傳安裝 sonar-l10n-zh-plugin-1.4.jar 語言包(http://docs.codehaus.org/display/SONAR/Chinese+Pack),重新打包部署後,背景報錯如下:
Error in Sonar.log : 2012.10.25 14:39:15 INFO org.sonar.INFO Register rules [squid/java]...2012.10.25 14:39:15 ERROR o.s.s.p.Platform The following rule (repository: squid) must have a description: Rule[id=<null>,name=<null>,key=ParsingError,configKey=ParsingError,plugin=squid,enabled=true,severity=MAJOR,cardinality=SINGLE]org.sonar.api.utils.SonarException: The following rule (repository: squid) must have a description: Rule[id=<null>,name=<null>,key=ParsingError,configKey=ParsingError,plugin=squid,enabled=true,severity=MAJOR,cardinality=SINGLE]at org.sonar.server.startup.RegisterRules.validateRule(RegisterRules.java:131) ~[classes/:na]at org.sonar.server.startup.RegisterRules.registerRepository(RegisterRules.java:103) ~[classes/:na]at...
(可參考http://jira.codehaus.org/browse/SONAR-3910)
解決方法:将 extensions\plugins\ 目錄下的jar包全部删除,重新加入本地語言包後,重新打包部署即可。
3、安裝、配置Sonar
Sonar的運作需要 JDK 1.5+ , 從 http://www.sonarqube.org/downloads/ 下載下傳sonar zip檔案,本文以3.6版本為例。
建立運作sonar的CentOS賬戶sonar,并設定賬戶密碼:
# useradd sonar
# passwd sonar
使用sonar賬戶登入CentOS。
Sonar預設內建了jetty容器,可以直接啟動提供服務,也可以通過腳本建構為war包,部署在tomcat容器中。
1)直接啟動
編輯.bash_profile,添加環境變量SONAR_HOME
$ vi $HOME/.bash_profile
修改成如下内容:
PATH=$PATH:$HOME/bin
SONAR_HOME=$HOME/sonar
export PATH SONAR_HOME
使環境變量生效
Source $HOME/.bash_profile
運作如下指令啟動sonar,其它作業系統sonar均提供了啟動腳本
$ ${SONAR_HOME}/bin/linux-x86-64/sonar.sh start
在浏覽器中通路: http://localhost:9000/ ,運作界面如下:

Sonar預設的端口是”9000”、預設的上下文路徑是”/”、預設的網絡接口是”0.0.0.0”,預設的管理者帳号和密碼為:admin/admin,這些參數都可以在配置檔案中修改:
$ vi ${SONAR_HOME}/conf/sonar.properties
2)作為Web項目,部署到Tomcat等應用伺服器中
a. 確定conf/sonar.properties、conf/wrapper.conf未被修改使用過
b. 執行如下指令生成war包,将生成的sonar.war部署到應用伺服器中
$ ${SONAR_HOME}/war/build-war.sh
c. 啟動Tomcat, 通過 http://localhost:8080/sonar 通路.
Tomcat安裝配置參見:CenOS系統中安裝Tomcat7并設定為自啟動服務
4、配置為自啟動服務
使用root賬戶或者開啟sudo權限操作。
建立自啟動腳本檔案/etc/init.d/sonar
# vi /etc/init.d/sonar
添加如下内容
#!/bin/sh
#
# rc file for SonarQube
#
# chkconfig: 345 96 10
# description: SonarQube system (www.sonarsource.org)
#
### BEGIN INIT INFO
# Provides: sonar
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: SonarQube system (www.sonarsource.org)
# Description: SonarQube system (www.sonarsource.org)
### END INIT INFO
/usr/bin/sonar $*
添加啟動服務
# ln -s $SONAR_HOME/bin/linux-x86-64/sonar.sh /usr/bin/sonar
# chmod 755 /etc/init.d/sonar
# chkconfig --add sonar
5、配置插件
a)插件介紹
Sonar支援多種插件,插件的下載下傳位址為:http://docs.codehaus.org/display/SONAR/Plugin+Library
将下載下傳後的插件上傳到${SONAR_HOME}extensions\plugins目錄下,重新啟動sonar。
sonar預設內建了Java Ecosystem插件,該插件是一組插件的合集
- Java [sonar-java-plugin]:java源代碼解析,計算名額等
- Squid [sonar-squid-java-plugin]:檢查違反Sonar定義規則的代碼
- Checkstyle [sonar-checkstyle-plugin]:使用CheckStyle檢查違反統一代碼編寫風格的代碼
- FindBugs [sonar-findbugs-plugin]:使用FindBugs檢查違反規則的缺陷代碼
- PMD [sonar-pmd-plugin]:使用pmd檢查違反規則的代碼
- Surefire [sonar-surefire-plugin]:使用Surefire執行單元測試
- Cobertura [sonar-cobertura-plugin]:使用Cobertura擷取代碼覆寫率
- JaCoCo [sonar-jacoco-plugin]:使用JaCOCO擷取代碼覆寫率
下面列出了一些常用的插件:
- JavaScript代碼檢查:http://docs.codehaus.org/display/SONAR/JavaScript+Plugin
- python代碼檢查:http://docs.codehaus.org/display/SONAR/Python+Plugin
- Web頁面檢查(HTML、JSP、JSF、Ruby、PHP等):http://docs.codehaus.org/display/SONAR/Web+Plugin
- xml檔案檢查:http://docs.codehaus.org/display/SONAR/XML+Plugin
- scm源碼庫統計分析:http://docs.codehaus.org/display/SONAR/SCM+Stats+Plugin
- 檔案度量:http://docs.codehaus.org/display/SONAR/Tab+Metrics+Plugin
- 中文語言包:http://docs.codehaus.org/display/SONAR/Chinese+Pack
- 時間表顯示度量結果:http://docs.codehaus.org/display/SONAR/Timeline+Plugin
- 度量結果演進圖:http://docs.codehaus.org/display/SONAR/Motion+Chart+Plugin
b)插件配置示例(本段内容來自http://www.ibm.com/developerworks/cn/java/j-lo-sonar/)
Sonar 的主要特色是對不同工具産生的檢查結果進行再加工處理,Sonar 還向使用者提供了對資料進行個性化處理的方法。
本節以 Technical Debt 插件為例說明如何通過設定參數影響最後的報告結果。首先了解一下這個插件中的“技術債務”的概念,這個概念最早是在 1992 年由 Ward Cunningham 在他的論文“The WyCash Portfolio Management System”中提出的,之後被軟體工程界接受并推廣,《重構》的作者 Martin Fowler 也在其 網站上對技術債務有所介紹。其實原理可以了解為“出來混早晚要還的”,目前不規範的代碼,會對以後産品修改的成本造成影響。
Soanr 的 Technical Debt 插件提供了預設的計算公式,通過對其中的權重參數進行配置,可以适應不同公司和項目對技術債務的計算。
以上的各項資料名額,可以根據自己公司和項目的不同情況進行設定,如圖所示:
例如預設參數下同一個項目的技術債務名額如下:
修改了參數後的結果為:
可見将 Average time to cover complexity of one (in hours) 從 0.2 修改為 0.01 後,Coverage 的權重變小了,進而達到忽略單元測試覆寫率的作用。不同的公司和項目可以根據需要調整各自的參數,參數的調優和政策不在本文的讨論範圍之内。
通過以上的示例可以看出,Sonar 使用不同類型的圖表顯示給使用者代碼品質的結果,并且這些圖表不是簡單地對單元測試覆寫率或者靜态檢測工具的結果進行顯示,而是根據軟體工程理論進行了二次加工後的結果,更加科學和直覺。
c)更新中心
以管理者使用者登入Sonar,進入配置->系統,選擇更新中心,如圖:
其中Available Plugins頁籤提供了可以選擇安裝的插件,System Updates可以線上更新Sonar。
下載下傳插件需要注意其中有些插件是需要購買才能使用的,其License類型為Commercial。
二、與jenkins內建
1、通過Maven進行內建
修改maven的主配置檔案(${MAVEN_HOME}/conf/settings.xml檔案或者 ~/.m2/settings.xml檔案),在其中增加通路Sonar資料庫及Sonar服務位址,添加如下配置:
<profile>
<id>sonar</id>
<properties>
<sonar.jdbc.url>jdbc:mysql://localhost:3306/sonar</sonar.jdbc.url>
<sonar.jdbc.driver>com.mysql.jdbc.Driver</sonar.jdbc.driver>
<sonar.jdbc.username>sonar</sonar.jdbc.username>
<sonar.jdbc.password>sonar</sonar.jdbc.password>
<sonar.host.url>http://localhost:9000</sonar.host.url> <!-- Sonar伺服器通路位址 -->
</properties>
</profile>
<activeProfiles>
<activeProfile>sonar</activeProfile>
</activeProfiles>
此處注意sonar.host.url位址應根據sonar部署情況修改
同樣,為了避免記憶體溢出,推薦增加記憶體堆棧的大小。設定MAVEN_OPTS環境變量:
set MAVEN_OPTS=”-Xmx512m -XX:MaxPermSize=256m”
使用Sonar
a. 運作Sonar伺服器;
b. 通過 mvn sonar:sonar 将代碼注入到Sonar中進行分析處理,并将處理結果以XML的形式儲存在資料庫中;
c. 通過浏覽器通路,顯示分析結果;
d. 持續運作Maven建構,會疊代顯示分析結果;
e. 可以顯式指定sonar插件的版本,如下:
<project>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.5.1</version>
</plugin>
</plugins>
</build>
</project>
f. 可以顯式的将sonar綁定到Maven生命周期中,如下:
<plugin>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<id>sonar</id>
<phase>site</phase>
<goals>
<goal>sonar</goal>
</goals>
</execution>
</executions>
</plugin>
此時,指定Maven的site聲明周期時,則會自動調用sonar.sonar 指令.
2、直接與Jenkins內建
在jenkins的插件管理中選擇安裝sonar jenkins plugin,該插件可以使項目每次建構都調用sonar進行代碼度量。
進入配置頁面對sonar插件進行配置,如下圖:
配置建構項目,增加Post Build Action:
應用程式建構時就會自動觸發Sonar對代碼的檢查