一、Sonar介绍
1.1简介
Sonar 不只是一个质量数据报告工具,更是代码质量管理平台。通过插件机制,Sonar可以集成不同的测试工具,代码分析工具,以及持续集成工具,比如pmd-cpd、checkstyle、findbugs、Jenkins。通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化,从而可以方便地对不同规模和种类的工程进行代码质量管理。同时 Sonar 还对大量的持续集成工具提供了接口支持,可以很方便地在持续集成中使用 Sonar。
1.2版本分类
社区版 | 免费 支持SonarQube + 60种插件 支持SonarLint 支持9种编程语言(Java、JavaScript、C#、TypeScript、Flex、Python、PHP、Web&XML) |
开发版 | (社区版基础上) 120$ 起 支持分支代码分析 支持SonarLint 语法提示 支持16种编程语言 |
企业版 | (开发版基础上) 15000$ 起 Portfolio management Executive reporting 支持20种编程语言 |
数据中心版 | (企业版基础上) 100000$ 起 Component redundancy Data integrity |
1.3用途
Sonar可以有效检测在程序开发过程中的七大问题:
1) 糟糕的复杂度分布
2) 重复代码
3) 缺乏单元测试
4) 没有代码标准
5) 没有足够的或者过多的注释
6) 潜在的BUG
7) 糟糕的设计
二、下载与安装
2.1下载
官网地址:https://www.sonarqube.org/downloads/
2.2下载插件
2.2.1插件库
Plugin+Library:https://docs.sonarqube.org/display/PLUG/Plugin+Library
SonarQubeCommunity:https://github.com/SonarQubeCommunity
汉化插件:https://github.com/SonarQubeCommunity/sonar-l10n-zh
2.2.2安装插件
将下载好的插件放到${SONAR_HOME}/extensions/plugins目录下,重启Sonar服务即可。
2.3 安装SonarQube
2.3.1 Windows平台安装
步骤一:创建数据库
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;
步骤二:修改${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&useConfigs=maxPerformance&useSSL=false
sonar.jdbc.driverClassName=com.mysql.jdbc.Driver
修改Sonar Web端口(可选配置)
Sonar Web 默认端口为9000,如需修改,可将 ${SONAR_HOME}/conf/sonar.properties中的sonar.web.port=9000改成其它端口值。 修改根目录(可选配置) 默认值为"/",启动后访问地址为 localhost:9000
若将sonar.web.context修改为/sonarqube,则启动后访问地址未localhost:9000/sonarqube。
步骤三:启动Sonar服务
找到安装目录下${SONAR_HOME}/bin/windows-x86-64/StartSonar.bat,双击运行即可。
启动画面如下:
Sonar安装初始化的数据库:
Sonar默认安装的插件:
步骤四:访问Sonar
访问地址:http://localhost:9000/sonarqube
默认账号:admin/admin
2.3.2 Linux平台安装
略
三、环境说明
SonarQube社区版 SonarQube 7.2(最新版本)
SonarQube 6.7.4 (LTS *) 【建议使用该版本】
Sonar Scanner 3.2.0
MySQL 5.6+
JDK 1.8+
Maven 3.1+
Jenkins 2.89.4+
四、Sonar Scanner
4.1官方教程
Analyzing with SonarQube Scanner
4.2下载
4.3安装
4.3.1 Windows平台安装
步骤一:将下载后的文件解压到任意目录
步骤二:设置变量
添加环境变量:SONAR_RUNNER_HOME
步骤三:验证安装是否成功
打开cmd,在命令行输入 sonar-scanner -v 如返回如下信息,则表示安装成功
>sonar-scanner -v
INFO: Scanner configuration file: E:\Software\SonarQubeScanner\bin\..\conf\sonar-scanner.properties
INFO: Project root configuration file: NONE
INFO: SonarQube Scanner 3.2.0.1227
INFO: Java 1.8.0_121 Oracle Corporation (64-bit)
INFO: Windows 10 10.0 amd64
4.3.2 Linux平台安装
略
4.4 使用
步骤一:在项目根目录,创建sonar-project.properties
步骤二:配置sonar-project.properties
# 项目的唯一标识
sonar.projectKey=learn-springboot-helloworld
# 项目名称
sonar.projectName=learn-springboot-helloworld
# 项目版本
sonar.projectVersion=trunk
# 项目源码目录
sonar.sources=src
# Java源码编译后目录(sonar-java插件4.12以上版本需要该配置)
sonar.java.binaries=target
# (可选配置)编程语言
sonar.language=java
# (可选配置)编码格式
sonar.sourceEncoding=UTF-8
# (可选配置)解决和SVN的冲突问题,当扫描目录存在.svn文件时,就报出扫描错误,设为true即可避免
sonar.scm.disabled=true
步骤三:打开cmd,进入项目根目录下,执行sonar-scanner -X命令
>sonar-scanner -X
08:31:13.384 INFO: Scanner configuration file: E:\Software\SonarQubeScanner\bin\..\conf\sonar-scanner.properties
08:31:13.404 INFO: Project root configuration file: D:\IDEAUWorkspace\codestudy\learn-springboot\ityouknow\learn-springboot-helloworld\sonar-project.properties
08:31:13.454 INFO: SonarQube Scanner 3.2.0.1227
08:31:13.454 INFO: Java 1.8.0_121 Oracle Corporation (64-bit)
08:31:13.454 INFO: Windows 10 10.0 amd64
08:31:14.444 DEBUG: keyStore is :
08:31:14.444 DEBUG: keyStore type is : jks
08:31:14.444 DEBUG: keyStore provider is :
08:31:14.444 DEBUG: init keystore
08:31:14.444 DEBUG: init keymanager of type SunX509
08:31:15.904 DEBUG: Create: C:\Users\Administrator\.sonar\cache
08:31:15.944 INFO: User cache: C:\Users\Administrator\.sonar\cache
08:31:15.944 DEBUG: Create: C:\Users\Administrator\.sonar\cache\_tmp
08:31:15.944 DEBUG: Extract sonar-scanner-api-batch in temp...
08:31:15.984 DEBUG: Get bootstrap index...
08:31:15.984 DEBUG: Download: http://localhost:9000/sonarqube/batch/index
08:31:16.184 DEBUG: Get bootstrap completed
08:31:16.234 DEBUG: Create isolated classloader...
08:31:16.334 DEBUG: Start temp cleaning...
08:31:16.344 DEBUG: Temp cleaning done
08:31:16.344 DEBUG: Execution getVersion
08:31:16.414 INFO: SonarQube server 7.1.0
08:31:16.414 INFO: Default locale: "zh_CN", source code encoding: "UTF-8"
08:31:16.414 DEBUG: Work directory: D:\IDEAUWorkspace\codestudy\learn-springboot\ityouknow\learn-springboot-helloworld\.scannerwork
08:31:16.424 DEBUG: Execution execute
08:31:17.544 INFO: Publish mode
08:31:17.814 INFO: Load global settings
08:31:17.934 DEBUG: GET 200 http://localhost:9000/sonarqube/api/settings/values.protobuf | time=100ms
08:31:17.984 INFO: Load global settings (done) | time=170ms
08:31:17.994 INFO: Server id: AWPQdPpfFHduclX46vyC
08:31:18.034 WARN: Property 'sonar.jdbc.url' is not supported any more. It will be ignored. There is no longer any DB connection to the SQ database.
08:31:18.034 WARN: Property 'sonar.jdbc.username' is not supported any more. It will be ignored. There is no longer any DB connection to the SQ database.
08:31:18.034 WARN: Property 'sonar.jdbc.password' is not supported any more. It will be ignored. There is no longer any DB connection to the SQ database.
08:31:18.044 INFO: User cache: C:\Users\Administrator\.sonar\cache
08:31:18.774 INFO: Load plugins index
08:31:18.814 DEBUG: GET 200 http://localhost:9000/sonarqube/api/plugins/installed | time=30ms
省略。。。。。。。
08:31:31.295 INFO: CPD calculation finished
08:31:31.605 INFO: Analysis report generated in 310ms, dir size=43 KB
08:31:31.775 INFO: Analysis reports compressed in 170ms, zip size=19 KB
08:31:31.785 INFO: Analysis report generated in D:\IDEAUWorkspace\codestudy\learn-springboot\ityouknow\learn-springboot-helloworld\.scannerwork\scanner-report
08:31:31.785 DEBUG: Upload report
08:31:35.565 DEBUG: POST 200 http://localhost:9000/sonarqube/api/ce/submit?projectKey=learn-springboot-helloworld&projectName=learn-springboot-helloworld | time=3780ms
08:31:35.595 INFO: Analysis report uploaded in 3810ms
08:31:35.595 INFO: ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/sonarqube/dashboard/index/learn-springboot-helloworld
08:31:35.595 INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
08:31:35.605 INFO: More about the report processing at http://localhost:9000/sonarqube/api/ce/task?id=AWUCWL-dozVBaxC9IEo-
08:31:35.605 DEBUG: Report metadata written to D:\IDEAUWorkspace\codestudy\learn-springboot\ityouknow\learn-springboot-helloworld\.scannerwork\report-task.txt
08:31:35.605 DEBUG: Post-jobs :
08:31:35.625 INFO: Task total time: 16.131 s
08:31:35.955 INFO: ------------------------------------------------------------------------
08:31:35.955 INFO: EXECUTION SUCCESS
08:31:35.965 INFO: ------------------------------------------------------------------------
08:31:35.965 INFO: Total time: 22.891s
08:31:36.155 INFO: Final Memory: 14M/148M
08:31:36.155 INFO: ------------------------------------------------------------------------
步骤四:查看分析结果
4.5 FAQ
在使用过程中发现问题:org.sonar.java.AnalysisException: Please provide compiled classes of your project with sonar.java.binaries property
问题原因:在sonar-java 4.12版本以上的插件,会存在该问题 解决办法:
1)sonar-java 4.12版本插件,在sonar-project.properties文件中还需配置sonar.java.binaries
2)替换${SONAR_HOME}/extensions/plugins中sonar-java-plugin*.jar为版本<= 4.12版本的插件,插件下载地址: sonar-java-plugin-4.12.0.11033.jar
五、与Maven集成
5.1官方教程
Analyzing with SonarQube Scanner for Maven
5.2集成说明
步骤一:配置settings.xml
在MAVEN_HOME/conf/settings.xml中,添加配置
<pluginGroups>
<pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
</pluginGroups>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.host.url>
http://localhost:9000/sonarqube
</sonar.host.url>
</properties>
</profile>
步骤二:使用mvn sonar:sonar命令执行代码分析
打开cmd,跳转的项目根目录,执行mvn sonar:sonar命令 如分析成功,会有如下信息返回:
>mvn sonar:sonar
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building learn-springboot-helloworld 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- sonar-maven-plugin:3.4.1.1168:sonar (default-cli) @ learn-springboot-helloworld ---
[INFO] User cache: C:\Users\Administrator\.sonar\cache
[INFO] SonarQube version: 7.1.0
[INFO] Default locale: "zh_CN", source code encoding: "UTF-8"
[INFO] Publish mode
[INFO] Load global settings
[INFO] Load global settings (done) | time=340ms
[INFO] Server id: AWPQdPpfFHduclX46vyC
[INFO] User cache: C:\Users\Administrator\.sonar\cache
[INFO] Load plugins index
[INFO] Load plugins index (done) | time=120ms
[INFO] Load/download plugins
[INFO] Plugin [l10nzh] defines 'l10nen' as base plugin. This metadata can be removed from manifest of l10n plugins since version 5.2.
[INFO] Load/download plugins (done) | time=50ms
[INFO] Process project properties
[INFO] Load project repositories
[INFO] Load project repositories (done) | time=693ms
[INFO] Load quality profiles
[INFO] Load quality profiles (done) | time=210ms
[INFO] Load active rules
[INFO] Load active rules (done) | time=1102ms
[INFO] Load metrics repository
[INFO] Load metrics repository (done) | time=100ms
[INFO] Project key: com.learn.springboot:learn-springboot-helloworld
[INFO] Project base dir: D:\IDEAUWorkspace\codestudy\learn-springboot\ityouknow\learn-springboot-helloworld
[INFO] ------------- Scan learn-springboot-helloworld
[INFO] Base dir: D:\IDEAUWorkspace\codestudy\learn-springboot\ityouknow\learn-springboot-helloworld
[INFO] Working dir: D:\IDEAUWorkspace\codestudy\learn-springboot\ityouknow\learn-springboot-helloworld\target\sonar
[INFO] Source paths: pom.xml, src/main/java
[INFO] Test paths: src/test/java
[INFO] Source encoding: UTF-8, default locale: zh_CN
[INFO] Load server rules
[INFO] Load server rules (done) | time=170ms
[INFO] Index files
[INFO] 7 files indexed
[INFO] Quality profile for java: Sonar way
[INFO] Quality profile for xml: Sonar way
[INFO] Sensor JavaSquidSensor [java]
[INFO] Configured Java source version (sonar.java.source): 8
[INFO] JavaClasspath initialization
[INFO] JavaClasspath initialization (done) | time=40ms
[INFO] JavaTestClasspath initialization
[INFO] JavaTestClasspath initialization (done) | time=20ms
[INFO] Java Main Files AST scan
[INFO] 3 source files to be analyzed
[INFO] 3/3 source files have been analyzed
[INFO] Java Main Files AST scan (done) | time=1362ms
[INFO] Java Test Files AST scan
[INFO] 3 source files to be analyzed
[INFO] 3/3 source files have been analyzed
[INFO] Java Test Files AST scan (done) | time=380ms
[INFO] Sensor JavaSquidSensor [java] (done) | time=3078ms
[INFO] Sensor FindBugs Sensor [findbugs]
[INFO] Loading findbugs plugin: D:\IDEAUWorkspace\codestudy\learn-springboot\ityouknow\learn-springboot-helloworld\target\sonar\findbugs\findsecbugs-plugin.jar
[INFO] Findbugs output report: D:\IDEAUWorkspace\codestudy\learn-springboot\ityouknow\learn-springboot-helloworld\target\sonar\findbugs-result.xml
[INFO] Sensor FindBugs Sensor [findbugs] (done) | time=8385ms
[INFO] Sensor SurefireSensor [java]
[INFO] parsing [D:\IDEAUWorkspace\codestudy\learn-springboot\ityouknow\learn-springboot-helloworld\target\surefire-reports]
[INFO] Sensor SurefireSensor [java] (done) | time=10ms
[INFO] Sensor JaCoCoSensor [java]
[INFO] Sensor JaCoCoSensor [java] (done) | time=0ms
[INFO] Sensor SonarJavaXmlFileSensor [java]
[INFO] 1 source files to be analyzed
[INFO] Sensor SonarJavaXmlFileSensor [java] (done) | time=1040ms
[INFO] 1/1 source files have been analyzed
[INFO] Sensor XML Sensor [xml]
[INFO] Sensor XML Sensor [xml] (done) | time=190ms
[INFO] Sensor Zero Coverage Sensor
[INFO] Sensor Zero Coverage Sensor (done) | time=40ms
[INFO] Sensor CPD Block Indexer
[INFO] Sensor CPD Block Indexer (done) | time=40ms
[INFO] 3 files had no CPD blocks
[INFO] Calculating CPD for 0 files
[INFO] CPD calculation finished
[INFO] Analysis report generated in 736ms, dir size=50 KB
[INFO] Analysis reports compressed in 190ms, zip size=19 KB
[INFO] Analysis report uploaded in 220ms
[INFO] ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/sonarqube/dashboard/index/com.learn.springboot:learn-springboot-helloworld
[INFO] Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
[INFO] More about the report processing at http://localhost:9000/sonarqube/api/ce/task?id=AWUCcagpozVBaxC9IEpH
[INFO] Task total time: 20.069 s
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 27.252 s
[INFO] Finished at: 2018-08-04T08:58:48+08:00
[INFO] Final Memory: 43M/364M
[INFO] ------------------------------------------------------------------------
步骤三:查看分析结果
访问:http://localhost:9000/sonarcube,就会看到该项目的分析结果
5.3 FAQ
执行mvn sonar:sonar命令时,提示:[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.1.1168:sonar (default-cli) on project learn-springboot-helloworld: Please provide compiled classes of your project with sonar.java.binaries property -> [Help 1]。
先检查JDK版本、Maven版本、Sonar版本、Sonar插件版本是否匹配,如都没有问题,那么先用mvn clean compile命令重新编译一下,再执行分析命令。当然,也可以使用mvn clean compile sonar:sonar命令完成整个操作。
六、与Jenkins集成
SonarQube与Jenkins集成,其实就是把Jenkins和Maven、SonarQube、SonarQube Scanner一起集成起来使用,利用Jenkins强大的持续集成能力,更方便地进行静态代码的质量分析。
6.1官方教程
Analyzing with SonarQube Scanner for Jenkins
6.2集成说明
步骤一:安装SonarQube的Jenkins插件
进入Jenkins 系统配置 》插件管理,搜索关键字SonarQube,找到SonarQube Scanner for Jenkins插件,安装即可。
注意:版本为2.89.2以前安装 SonarQube Scanner 会提示插件有问题,需要将jenkins升级到2.89.4以上版本
步骤二:配置全局工具
打开Jenkins ,进入 系统配置 》全局工具配置,配置JDK、SonarQube Scanner等
步骤三:配置SonarQube servers
打开Jenkins ,进入 系统配置 》系统设置,配置SonarQube servers ,其中
Name:登录Sonar时,注册的账号
Server URL:默认为localhost:9000,如果安装SonarQube时,修改sonar.web.context为sonarqube,那么这个值就是localhost:9000/sonarqube
Server authentication token:注册账号时生成的token,如果忘记了,可以在 我的账号 》安全,重新生成令牌。
步骤四:配置构建任务
$JOB_NAME:Jenkins自带的环境变量,表示当前任务的名称
$WORKSPACE:Jenkins自带的环境变量,表示当前任务的工作目录
七、在IDE中使用
7.1 SonarLint与Eclipse
略
7.2 SonarLint与Intellij IDEA
官方教程:https://www.sonarlint.org/intellij/
1)安装SonarLint
在plugins中搜索SonarLint,Install后重启
2)配置SonarLint
配置SonarQube Servers(可选配置)
Token是在首次登录Sonar Web的时候配置的,如果忘记了,可以在 我的账号 》安全 里面,重新生成令牌。
配置SonarQube Project(可选配置)
3)使用SonarLint
如果配置了SonarQube Servers和SonarQube Project,那么可以通过Search in list,选中服务器上的项目,然后执行扫描分析;也可以不进行上述配置,直接使用SonarLint插件执行代码分析。
执行扫描,使用SonarLint插件分析代码
分析结果如下图所示:
左侧显示的时代码存在的问题以及严重级别,右侧Rule可以看对应问题的分析和改进建议。
在编码时,也可以看到SonarLint给出的实时提示
八、总结
通过开源代码质量分析平台SonarQube,结合Findbugs、Checkstyle等工具,我们可以检查出项目代码的漏洞和潜在的逻辑问题,从而引导开发人员编写高质量的代码,SonarQube可以与Maven、Jenkins结合使用,也可以在Eclipse、Intellij IDEA等IDE工具中使用,工具本身已经具备很强大的代码分析能力,但更重要的是,在项目团队中,应当鼓励并强调“写优秀的代码”的重要性,在项目管理中,逐渐建立起代码质量审查的机制,才能有效提高项目代码质量的整体水平。
附录:参考资料
6、 解决新版sonar-java插件需要配置sonar.java.binaries参数的问题
7、 【代码审计】使用SonarQube进行代码质量分析管理
8、 【代码审计】SonarQube配置外部数据存储和基本使用