DevOps之持续集成SonarQube代码质量扫描


      SonarQube是一个用于代码质量检测管理的开放平台,可以集成不同的检测工具,代码分析工具,以及持续集成工具。SonarQube 并不是简单地把不同的代码检查工具结果直接显示在 Web 页面上,而是通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化。
  SonarQube不仅提供了对 IDE 的支持,可以在Eclipse和IntelliJ IDEA这些工具里联机查看结果;同时 SonarQube 还对大量的持续集成工具提供了接口支持,可以很方便地在持续集成中使用SonarQube,另外Sonar的插件还可以对Java以外的其他编程语言提供支持。

1.编码规范:是否遵守了编码规范,遵循了最佳实践。
2.潜在的BUG:可能在最坏情况下出现问题的代码,以及存在安全漏洞的代码。
3.文档和注释:过少(缺少必要信息)、过多(没有信息量)、过时的文档或注释。
4.重复代码:违反了Don’tRepeat Yourself原则。
5.复杂度:代码结构太复杂(如圈复杂度高),难以理解、测试和维护。
6.测试覆盖率:编写单元测试,特别是针对复杂代码的测试覆盖是否足够。
7.设计与架构:是否高内聚、低耦合,依赖最少。

1、部署SonarQube

官方地址
https://www.sonarqube.org/downloads/

 ①Sonar需要至少JDK 1.8及以上版本

#解压上传的jdk#
tar xf jdk-8u161-linux-x64.tar.gz -C /usr/local/
ln -s /usr/local/jdk1.8.0_161 /usr/local/jdk
ln -s /usr/local/jdk/bin/java /usr/bin/java
#配置环境变量#
vim /etc/profile
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH
source /etc/profile

②部署SonarQube数据库(mysql5.6 或者更高版本)

wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
rpm -ivh mysql-community-release-el7-5.noarch.rpm
yum install mysql-community-server
systemctl start mysqld.service
#初次安装mysql是root账户是没有密码的#
set password for ‘root’@‘localhost’ = password('mypasswd');
flush privileges;

执行SQL语句

CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar@pw';
GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar@pw';
FLUSH PRIVILEGES;

配置Sonar数据库

vim /usr/local/sonarqube/conf/sonar.properties

sonar.web.host=0.0.0.0 #监听的IP地址
sonar.web.port=9003 #监听的端口
sonar.jdbc.username=sonar #数据库用户名
sonar.jdbc.password=sonar@pw #数据库密码
sonar.jdbc.url=jdbc:mysql://192.168.29.176:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance

Oracle数据库

手动复制驱动类到${SONAR_HOME}/extensions/jdbc-driver/oracle/目录下

参考官方文档:http://docs.sonarqube.org/display/HOME/SonarQube+Platform

③启动SonarQube

/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start
tail /usr/local/sonarqube/logs/sonar.log #日志文件

Web页面登陆:http://IP:9003 默认为9000端口,默认用户名密码admin/admin

④SonarQube插件

存放插件目录/usr/local/sonarqube/extensions/plugins/

Sonar页面汉化:Chinese Pack

640?wx_fmt=png

2、SonarQube Scanner扫描器

①官方文档

https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner
#Sonar通过Scanner(扫描器)来对代码进行质量分析#

②下载Scanner扫描器

#上传插件包:sonar-scanner-2.8.zip#
unzip sonar-scanner-2.8.zip
mv sonar-scanner-2.8 /usr/local/
ln -s /usr/local/sonar-scanner-2.8/ /usr/local/sonar-scanner

③SonarQube集成Scanner

vim /usr/local/sonar-scanner/conf/sonar-scanner.properties
sonar.host.url=http://192.168.29.175:9006 #sonar地址
sonar.sourceEncoding=UTF-8 #字符集
sonar.jdbc.username=sonar #数据库账号
sonar.jdbc.password=sonar@pw #数据库密码
sonar.jdbc.url=jdbc:mysql://192.168.29.175:3306/sonar?useUnicode=true&characterEncoding=utf8 #数据库连接地址

④项目代码库测试

github:https://github.com/SonarSource/sonar-examples
下载软件包:https://github.com/SonarSource/sonar-examples/archive/master.zip

⑤项目代码下配置sonar-project.properties

sonar.projectKey=
sonar.projectName=#这个名称会显示在Sonar的web页面
sonar.projectVersion=
sonar.sources=. #源码路径
sonar.language=java
sonar.sourceEncoding=UTF-8

⑥代码质量扫描

#进入到项目下执行#
/usr/local/sonar-scanner/bin/sonar-scanner

部分扫描Log信息

INFO: Java Main Files AST scan (done) | time=28351ms
INFO: Java Test Files AST scan
INFO: 0 source files to be analyzed
INFO: 502/502 source files have been analyzed
INFO: Java Test Files AST scan (done) | time=0ms
INFO: Sensor JavaSquidSensor [java] (done) | time=28795ms
INFO: Sensor NoSonar Sensor [php]
INFO: Sensor NoSonar Sensor [php] (done) | time=0ms
INFO: Sensor CoberturaSensor [cobertura]
INFO: 0/0 source files have been analyzed
WARN: Cobertura report not found at /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/site/cobertura/coverage.xml
INFO: Sensor CoberturaSensor [cobertura] (done) | time=1ms
INFO: Sensor Coverage Report Import [csharp]
INFO: Sensor Coverage Report Import [csharp] (done) | time=0ms
INFO: Sensor Coverage Report Import [csharp]
INFO: Sensor Coverage Report Import [csharp] (done) | time=0ms
INFO: Sensor Unit Test Results Import [csharp]
INFO: Sensor Unit Test Results Import [csharp] (done) | time=0ms
INFO: Sensor SurefireSensor [java]
INFO: parsing /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/surefire-reports
INFO: Sensor SurefireSensor [java] (done) | time=1ms
INFO: Sensor JaCoCoSensor [java]
INFO: JaCoCoSensor: JaCoCo report not found : /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/jacoco.exec
INFO: Sensor JaCoCoSensor [java] (done) | time=1ms
INFO: Sensor JaCoCoItSensor [java]
INFO: JaCoCoItSensor: JaCoCo IT report not found: /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/jacoco-it.exec
INFO: Sensor JaCoCoItSensor [java] (done) | time=0ms
INFO: Sensor JaCoCoOverallSensor [java]
INFO: Sensor JaCoCoOverallSensor [java] (done) | time=0ms
INFO: Sensor XmlFileSensor [java]
INFO: Sensor XmlFileSensor [java] (done) | time=2ms
INFO: Sensor Analyzer for "php.ini" files [php]

3、Jenkins集成SonarQube

①安装插件:SonarQube Scanner

Jenkins-系统管理-插件管理

②Jenkins集成Sonar

640?wx_fmt=png

 4、SonarQube遇到的问题

①ERROR: Error during SonarQube Scanner execution

ERROR: Error during SonarQube Scanner execution
org.sonar.squidbridge.api.AnalysisException: Please provide compiled classes of your project with sonar.java.binaries property
at org.sonar.java.JavaClasspath.init(JavaClasspath.java:59)
at org.sonar.java.AbstractJavaClasspath.getElements(AbstractJavaClasspath.java:281)
at org.sonar.java.SonarComponents.getJavaClasspath(SonarComponents.java:141)
at org.sonar.java.JavaSquid.<init>(JavaSquid.java:83)
at org.sonar.plugins.java.JavaSquidSensor.execute(JavaSquidSensor.java:83)
at org.sonar.scanner.sensor.SensorWrapper.analyse(SensorWrapper.java:53)
at org.sonar.scanner.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:88)
at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:82)
at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:68)
at org.sonar.scanner.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:88)
at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:177)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:291)
at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:286)
at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:264)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
at org.sonar.scanner.task.ScanTask.execute(ScanTask.java:48)
at org.sonar.scanner.task.TaskContainer.doAfterStart(TaskContainer.java:84)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
at org.sonar.scanner.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:121)
at org.sonar.batch.bootstrapper.Batch.doExecuteTask(Batch.java:116)
at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:111)
at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
at com.sun.proxy.$Proxy0.execute(Unknown Source)
at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:233)
at org.sonarsource.scanner.api.EmbeddedScanner.runAnalysis(EmbeddedScanner.java:151)
at org.sonarsource.scanner.cli.Main.runAnalysis(Main.java:110)
at org.sonarsource.scanner.cli.Main.execute(Main.java:74)
at org.sonarsource.scanner.cli.Main.main(Main.java:61)
ERROR:
ERROR: Re-run SonarQube Scanner using the -X switch to enable full debug logging.
[Pipeline]

解决:SonarQube6.7.6版本下面的sonar-java插件为 sonar-java-plugin-4.15.0.12310.jar

更换为其他版本:sonar-java-plugin-4.3.0.7717.jar

插件地址:

https://github.com/SonarSource/sonar-java

      SonarQube是一个用于代码质量检测管理的开放平台,可以集成不同的检测工具,代码分析工具,以及持续集成工具。SonarQube 并不是简单地把不同的代码检查工具结果直接显示在 Web 页面上,而是通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化。
  SonarQube不仅提供了对 IDE 的支持,可以在Eclipse和IntelliJ IDEA这些工具里联机查看结果;同时 SonarQube 还对大量的持续集成工具提供了接口支持,可以很方便地在持续集成中使用SonarQube,另外Sonar的插件还可以对Java以外的其他编程语言提供支持。

1.编码规范:是否遵守了编码规范,遵循了最佳实践。
2.潜在的BUG:可能在最坏情况下出现问题的代码,以及存在安全漏洞的代码。
3.文档和注释:过少(缺少必要信息)、过多(没有信息量)、过时的文档或注释。
4.重复代码:违反了Don’tRepeat Yourself原则。
5.复杂度:代码结构太复杂(如圈复杂度高),难以理解、测试和维护。
6.测试覆盖率:编写单元测试,特别是针对复杂代码的测试覆盖是否足够。
7.设计与架构:是否高内聚、低耦合,依赖最少。

1、部署SonarQube

官方地址
https://www.sonarqube.org/downloads/

 ①Sonar需要至少JDK 1.8及以上版本

#解压上传的jdk#
tar xf jdk-8u161-linux-x64.tar.gz -C /usr/local/
ln -s /usr/local/jdk1.8.0_161 /usr/local/jdk
ln -s /usr/local/jdk/bin/java /usr/bin/java
#配置环境变量#
vim /etc/profile
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH
source /etc/profile

②部署SonarQube数据库(mysql5.6 或者更高版本)

wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
rpm -ivh mysql-community-release-el7-5.noarch.rpm
yum install mysql-community-server
systemctl start mysqld.service
#初次安装mysql是root账户是没有密码的#
set password for ‘root’@‘localhost’ = password('mypasswd');
flush privileges;

执行SQL语句

CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar@pw';
GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar@pw';
FLUSH PRIVILEGES;

配置Sonar数据库

vim /usr/local/sonarqube/conf/sonar.properties

sonar.web.host=0.0.0.0 #监听的IP地址
sonar.web.port=9003 #监听的端口
sonar.jdbc.username=sonar #数据库用户名
sonar.jdbc.password=sonar@pw #数据库密码
sonar.jdbc.url=jdbc:mysql://192.168.29.176:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance

Oracle数据库

手动复制驱动类到${SONAR_HOME}/extensions/jdbc-driver/oracle/目录下

参考官方文档:http://docs.sonarqube.org/display/HOME/SonarQube+Platform

③启动SonarQube

/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start
tail /usr/local/sonarqube/logs/sonar.log #日志文件

Web页面登陆:http://IP:9003 默认为9000端口,默认用户名密码admin/admin

④SonarQube插件

存放插件目录/usr/local/sonarqube/extensions/plugins/

Sonar页面汉化:Chinese Pack

640?wx_fmt=png

2、SonarQube Scanner扫描器

①官方文档

https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner
#Sonar通过Scanner(扫描器)来对代码进行质量分析#

②下载Scanner扫描器

#上传插件包:sonar-scanner-2.8.zip#
unzip sonar-scanner-2.8.zip
mv sonar-scanner-2.8 /usr/local/
ln -s /usr/local/sonar-scanner-2.8/ /usr/local/sonar-scanner

③SonarQube集成Scanner

vim /usr/local/sonar-scanner/conf/sonar-scanner.properties
sonar.host.url=http://192.168.29.175:9006 #sonar地址
sonar.sourceEncoding=UTF-8 #字符集
sonar.jdbc.username=sonar #数据库账号
sonar.jdbc.password=sonar@pw #数据库密码
sonar.jdbc.url=jdbc:mysql://192.168.29.175:3306/sonar?useUnicode=true&amp;characterEncoding=utf8 #数据库连接地址

④项目代码库测试

github:https://github.com/SonarSource/sonar-examples
下载软件包:https://github.com/SonarSource/sonar-examples/archive/master.zip

⑤项目代码下配置sonar-project.properties

sonar.projectKey=
sonar.projectName=#这个名称会显示在Sonar的web页面
sonar.projectVersion=
sonar.sources=. #源码路径
sonar.language=java
sonar.sourceEncoding=UTF-8

⑥代码质量扫描

#进入到项目下执行#
/usr/local/sonar-scanner/bin/sonar-scanner

部分扫描Log信息

INFO: Java Main Files AST scan (done) | time=28351ms
INFO: Java Test Files AST scan
INFO: 0 source files to be analyzed
INFO: 502/502 source files have been analyzed
INFO: Java Test Files AST scan (done) | time=0ms
INFO: Sensor JavaSquidSensor [java] (done) | time=28795ms
INFO: Sensor NoSonar Sensor [php]
INFO: Sensor NoSonar Sensor [php] (done) | time=0ms
INFO: Sensor CoberturaSensor [cobertura]
INFO: 0/0 source files have been analyzed
WARN: Cobertura report not found at /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/site/cobertura/coverage.xml
INFO: Sensor CoberturaSensor [cobertura] (done) | time=1ms
INFO: Sensor Coverage Report Import [csharp]
INFO: Sensor Coverage Report Import [csharp] (done) | time=0ms
INFO: Sensor Coverage Report Import [csharp]
INFO: Sensor Coverage Report Import [csharp] (done) | time=0ms
INFO: Sensor Unit Test Results Import [csharp]
INFO: Sensor Unit Test Results Import [csharp] (done) | time=0ms
INFO: Sensor SurefireSensor [java]
INFO: parsing /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/surefire-reports
INFO: Sensor SurefireSensor [java] (done) | time=1ms
INFO: Sensor JaCoCoSensor [java]
INFO: JaCoCoSensor: JaCoCo report not found : /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/jacoco.exec
INFO: Sensor JaCoCoSensor [java] (done) | time=1ms
INFO: Sensor JaCoCoItSensor [java]
INFO: JaCoCoItSensor: JaCoCo IT report not found: /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/jacoco-it.exec
INFO: Sensor JaCoCoItSensor [java] (done) | time=0ms
INFO: Sensor JaCoCoOverallSensor [java]
INFO: Sensor JaCoCoOverallSensor [java] (done) | time=0ms
INFO: Sensor XmlFileSensor [java]
INFO: Sensor XmlFileSensor [java] (done) | time=2ms
INFO: Sensor Analyzer for "php.ini" files [php]

3、Jenkins集成SonarQube

①安装插件:SonarQube Scanner

Jenkins-系统管理-插件管理

②Jenkins集成Sonar

640?wx_fmt=png

 4、SonarQube遇到的问题

①ERROR: Error during SonarQube Scanner execution

ERROR: Error during SonarQube Scanner execution
org.sonar.squidbridge.api.AnalysisException: Please provide compiled classes of your project with sonar.java.binaries property
at org.sonar.java.JavaClasspath.init(JavaClasspath.java:59)
at org.sonar.java.AbstractJavaClasspath.getElements(AbstractJavaClasspath.java:281)
at org.sonar.java.SonarComponents.getJavaClasspath(SonarComponents.java:141)
at org.sonar.java.JavaSquid.<init>(JavaSquid.java:83)
at org.sonar.plugins.java.JavaSquidSensor.execute(JavaSquidSensor.java:83)
at org.sonar.scanner.sensor.SensorWrapper.analyse(SensorWrapper.java:53)
at org.sonar.scanner.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:88)
at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:82)
at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:68)
at org.sonar.scanner.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:88)
at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:177)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:291)
at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:286)
at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:264)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
at org.sonar.scanner.task.ScanTask.execute(ScanTask.java:48)
at org.sonar.scanner.task.TaskContainer.doAfterStart(TaskContainer.java:84)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
at org.sonar.scanner.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:121)
at org.sonar.batch.bootstrapper.Batch.doExecuteTask(Batch.java:116)
at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:111)
at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
at com.sun.proxy.$Proxy0.execute(Unknown Source)
at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:233)
at org.sonarsource.scanner.api.EmbeddedScanner.runAnalysis(EmbeddedScanner.java:151)
at org.sonarsource.scanner.cli.Main.runAnalysis(Main.java:110)
at org.sonarsource.scanner.cli.Main.execute(Main.java:74)
at org.sonarsource.scanner.cli.Main.main(Main.java:61)
ERROR:
ERROR: Re-run SonarQube Scanner using the -X switch to enable full debug logging.
[Pipeline]

解决:SonarQube6.7.6版本下面的sonar-java插件为 sonar-java-plugin-4.15.0.12310.jar

更换为其他版本:sonar-java-plugin-4.3.0.7717.jar

插件地址:

https://github.com/SonarSource/sonar-java      SonarQube是一个用于代码质量检测管理的开放平台,可以集成不同的检测工具,代码分析工具,以及持续集成工具。SonarQube 并不是简单地把不同的代码检查工具结果直接显示在 Web 页面上,而是通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化。

  SonarQube不仅提供了对 IDE 的支持,可以在Eclipse和IntelliJ IDEA这些工具里联机查看结果;同时 SonarQube 还对大量的持续集成工具提供了接口支持,可以很方便地在持续集成中使用SonarQube,另外Sonar的插件还可以对Java以外的其他编程语言提供支持。

1.编码规范:是否遵守了编码规范,遵循了最佳实践。
2.潜在的BUG:可能在最坏情况下出现问题的代码,以及存在安全漏洞的代码。
3.文档和注释:过少(缺少必要信息)、过多(没有信息量)、过时的文档或注释。
4.重复代码:违反了Don’tRepeat Yourself原则。
5.复杂度:代码结构太复杂(如圈复杂度高),难以理解、测试和维护。
6.测试覆盖率:编写单元测试,特别是针对复杂代码的测试覆盖是否足够。
7.设计与架构:是否高内聚、低耦合,依赖最少。

1、部署SonarQube

官方地址
https://www.sonarqube.org/downloads/

 ①Sonar需要至少JDK 1.8及以上版本

#解压上传的jdk#
tar xf jdk-8u161-linux-x64.tar.gz -C /usr/local/
ln -s /usr/local/jdk1.8.0_161 /usr/local/jdk
ln -s /usr/local/jdk/bin/java /usr/bin/java
#配置环境变量#
vim /etc/profile
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH
source /etc/profile

②部署SonarQube数据库(mysql5.6 或者更高版本)

wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
rpm -ivh mysql-community-release-el7-5.noarch.rpm
yum install mysql-community-server
systemctl start mysqld.service
#初次安装mysql是root账户是没有密码的#
set password for ‘root’@‘localhost’ = password('mypasswd');
flush privileges;

执行SQL语句

CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar@pw';
GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar@pw';
FLUSH PRIVILEGES;

配置Sonar数据库

vim /usr/local/sonarqube/conf/sonar.properties

sonar.web.host=0.0.0.0 #监听的IP地址
sonar.web.port=9003 #监听的端口
sonar.jdbc.username=sonar #数据库用户名
sonar.jdbc.password=sonar@pw #数据库密码
sonar.jdbc.url=jdbc:mysql://192.168.29.176:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance

Oracle数据库

手动复制驱动类到${SONAR_HOME}/extensions/jdbc-driver/oracle/目录下

参考官方文档:http://docs.sonarqube.org/display/HOME/SonarQube+Platform

③启动SonarQube

/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start
tail /usr/local/sonarqube/logs/sonar.log #日志文件

Web页面登陆:http://IP:9003 默认为9000端口,默认用户名密码admin/admin

④SonarQube插件

存放插件目录/usr/local/sonarqube/extensions/plugins/

Sonar页面汉化:Chinese Pack

640?wx_fmt=png

2、SonarQube Scanner扫描器

①官方文档

https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner
#Sonar通过Scanner(扫描器)来对代码进行质量分析#

②下载Scanner扫描器

#上传插件包:sonar-scanner-2.8.zip#
unzip sonar-scanner-2.8.zip
mv sonar-scanner-2.8 /usr/local/
ln -s /usr/local/sonar-scanner-2.8/ /usr/local/sonar-scanner

③SonarQube集成Scanner

vim /usr/local/sonar-scanner/conf/sonar-scanner.properties
sonar.host.url=http://192.168.29.175:9006 #sonar地址
sonar.sourceEncoding=UTF-8 #字符集
sonar.jdbc.username=sonar #数据库账号
sonar.jdbc.password=sonar@pw #数据库密码
sonar.jdbc.url=jdbc:mysql://192.168.29.175:3306/sonar?useUnicode=true&amp;characterEncoding=utf8 #数据库连接地址

④项目代码库测试

github:https://github.com/SonarSource/sonar-examples
下载软件包:https://github.com/SonarSource/sonar-examples/archive/master.zip

⑤项目代码下配置sonar-project.properties

sonar.projectKey=
sonar.projectName=#这个名称会显示在Sonar的web页面
sonar.projectVersion=
sonar.sources=. #源码路径
sonar.language=java
sonar.sourceEncoding=UTF-8

⑥代码质量扫描

#进入到项目下执行#
/usr/local/sonar-scanner/bin/sonar-scanner

部分扫描Log信息

INFO: Java Main Files AST scan (done) | time=28351ms
INFO: Java Test Files AST scan
INFO: 0 source files to be analyzed
INFO: 502/502 source files have been analyzed
INFO: Java Test Files AST scan (done) | time=0ms
INFO: Sensor JavaSquidSensor [java] (done) | time=28795ms
INFO: Sensor NoSonar Sensor [php]
INFO: Sensor NoSonar Sensor [php] (done) | time=0ms
INFO: Sensor CoberturaSensor [cobertura]
INFO: 0/0 source files have been analyzed
WARN: Cobertura report not found at /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/site/cobertura/coverage.xml
INFO: Sensor CoberturaSensor [cobertura] (done) | time=1ms
INFO: Sensor Coverage Report Import [csharp]
INFO: Sensor Coverage Report Import [csharp] (done) | time=0ms
INFO: Sensor Coverage Report Import [csharp]
INFO: Sensor Coverage Report Import [csharp] (done) | time=0ms
INFO: Sensor Unit Test Results Import [csharp]
INFO: Sensor Unit Test Results Import [csharp] (done) | time=0ms
INFO: Sensor SurefireSensor [java]
INFO: parsing /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/surefire-reports
INFO: Sensor SurefireSensor [java] (done) | time=1ms
INFO: Sensor JaCoCoSensor [java]
INFO: JaCoCoSensor: JaCoCo report not found : /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/jacoco.exec
INFO: Sensor JaCoCoSensor [java] (done) | time=1ms
INFO: Sensor JaCoCoItSensor [java]
INFO: JaCoCoItSensor: JaCoCo IT report not found: /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/jacoco-it.exec
INFO: Sensor JaCoCoItSensor [java] (done) | time=0ms
INFO: Sensor JaCoCoOverallSensor [java]
INFO: Sensor JaCoCoOverallSensor [java] (done) | time=0ms
INFO: Sensor XmlFileSensor [java]
INFO: Sensor XmlFileSensor [java] (done) | time=2ms
INFO: Sensor Analyzer for "php.ini" files [php]

3、Jenkins集成SonarQube

①安装插件:SonarQube Scanner

Jenkins-系统管理-插件管理

②Jenkins集成Sonar

640?wx_fmt=png

 4、SonarQube遇到的问题

①ERROR: Error during SonarQube Scanner execution

ERROR: Error during SonarQube Scanner execution
org.sonar.squidbridge.api.AnalysisException: Please provide compiled classes of your project with sonar.java.binaries property
at org.sonar.java.JavaClasspath.init(JavaClasspath.java:59)
at org.sonar.java.AbstractJavaClasspath.getElements(AbstractJavaClasspath.java:281)
at org.sonar.java.SonarComponents.getJavaClasspath(SonarComponents.java:141)
at org.sonar.java.JavaSquid.<init>(JavaSquid.java:83)
at org.sonar.plugins.java.JavaSquidSensor.execute(JavaSquidSensor.java:83)
at org.sonar.scanner.sensor.SensorWrapper.analyse(SensorWrapper.java:53)
at org.sonar.scanner.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:88)
at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:82)
at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:68)
at org.sonar.scanner.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:88)
at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:177)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:291)
at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:286)
at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:264)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
at org.sonar.scanner.task.ScanTask.execute(ScanTask.java:48)
at org.sonar.scanner.task.TaskContainer.doAfterStart(TaskContainer.java:84)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
at org.sonar.scanner.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:121)
at org.sonar.batch.bootstrapper.Batch.doExecuteTask(Batch.java:116)
at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:111)
at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
at com.sun.proxy.$Proxy0.execute(Unknown Source)
at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:233)
at org.sonarsource.scanner.api.EmbeddedScanner.runAnalysis(EmbeddedScanner.java:151)
at org.sonarsource.scanner.cli.Main.runAnalysis(Main.java:110)
at org.sonarsource.scanner.cli.Main.execute(Main.java:74)
at org.sonarsource.scanner.cli.Main.main(Main.java:61)
ERROR:
ERROR: Re-run SonarQube Scanner using the -X switch to enable full debug logging.
[Pipeline]

解决:SonarQube6.7.6版本下面的sonar-java插件为 sonar-java-plugin-4.15.0.12310.jar

更换为其他版本:sonar-java-plugin-4.3.0.7717.jar

插件地址:

https://github.com/SonarSource/sonar-java

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314030.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

变量(网络流模型)

变量 首先最终答案的形式一定是每个变量前面对应一个系数&#xff0c;然后加上一些绝对值&#xff0c;由于每个变量只有两种取法&#xff0c;所以我们考虑使用最小割处理&#xff0c;对于每个变量建一个点分别连到S和T&#xff0c;然后表示选择取哪个&#xff0c;然后会有一边是…

使用VS Code 开发.NET CORE 程序指南

1. 前言近两年来&#xff0c;很多前端的同学都开始将 VSCode 作为前端主力开发工具&#xff0c;其丰富的扩展给程序开发尤其是前端开发带来了很多便利&#xff0c;但是作为微软主力语言的 .NET&#xff0c;却由于有宇宙第一IDE Visual Studio存在&#xff0c;很少有看到有后端同…

用pythonnet为计算机视觉做图像整理

中国的.NETer是国内技术的另类&#xff0c;当他们强调.NET也可以做啥啥时都会给别的技术藐视&#xff0c;毕竟主流都不用.NET。本人这几年其实花在.NET时间也少&#xff0c;都投入在Python/Go社区。可我还是有点工作外的寄托&#xff0c;就是让.NET也有一个很好的推广&#xff…

ABP虚拟文件系统(VirtualFileSystem)实例------定制菜单栏显示用户姓名

ABP默认的MVC启动模板在登录后, 右上角显示的是用户名:如果想让它显示用户的姓名该如何做呢?这就需要用到ABP一个非常强大的功能------虚拟文件系统.前期准备使用ABP CLI创建一个名为AbpStudy的ASP.NET MVC项目:abp new AbpStudy关于MVC的启动模板可以看文档, 这里就不赘述.虚…

.NET中国峰会 参与意愿调查

2014年微软组织成立.NET基金会&#xff0c;微软在成为主要的开源参与者的道路上又前进了一步。2014年以来已经有众多知名公司加入.NET基金会, 仅在平台项目中&#xff0c;.NET平台上有87&#xff05;贡献者其实不在Microsoft工作。将.NET基金会变成一个更加多样化和成员驱动的组…

听我的!美国科技公司这样做Code Review

Code Review&#xff0c;在当代的软件开发中占有重要的一环。虽然国内各大主流公司都已经参照国外同行设立了比较严格的Code Review机制&#xff0c;但是还是有好多大型软件公司以及中小型软件公司还未推行这一重要制度。那么在美国的科技企业中&#xff0c;Code Review推行的怎…

程序员过关斩将--互联网人必备知识cookie和session认证

菜菜&#xff0c;上次你说的cookie和session的文章&#xff0c;我觉得不太具体那你想怎么样具体呢&#xff1f;我自己从网上查了一下&#xff0c;很多关于cookie和session认证的&#xff0c;能不能给我讲讲用户认证呀&#xff0c;可以呀这样我下次再去面试&#xff0c;有可能会…

2019-03-15-算法-进化(有效的数独)

题目描述 判断一个 9x9 的数独是否有效。只需要根据以下规则&#xff0c;验证已经填入的数字是否有效即可。数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。上图是一个部分填充的有效的数独。 数独…

net core WebApi——尝试企业微信来开发企业内部应用

前言这几天忙活着别的东西&#xff0c;耽误了很长时间&#xff0c;从文件操作完了之后就在考虑着下一步鼓捣点儿啥&#xff0c;因为最开始的业务开发就是企业微信相关的&#xff0c;这刚好来做个内部应用的小例子玩玩。企业微信前身是企业号&#xff0c;当时微信主推的还是公众…

微软发布了开发社区采用.NET Standard的最新信息

最近&#xff0c;微软发布了开发社区当前采用.NET Standard的最新信息。.NET Standard是API的正式规范&#xff0c;现有.NET实现在不同平台的是通用的&#xff08;从而允许跨平台开发&#xff09;。当前规范&#xff08;版本2.0&#xff09;在两年前发布&#xff0c;在.NET Cor…

卓语言对泛型类的使用

上次发了中文编程语言卓语言《小卓.NET中文编程特点介绍》。这篇文章来看下卓语言对泛型类的使用。泛型是现代编程语言很重要的功能。C#语言可以完全定义和使用泛型类型。卓语言是面向广大非专业人员的&#xff0c;为了减低编程难度&#xff0c;没有实现定义泛型类型&#xff0…

AT2675 [AGC018F] Two Trees(欧拉回路)

AT2675 [AGC018F] Two Trees 首先我们看到1或-1&#xff0c;那么就是限制差距在1以内&#xff0c;然后我们可以想到构造一些东西来满足这种东西&#xff0c;然后我们经常利用的就是欧拉回路。 首先这是两个树&#xff0c;然后我们可以根据儿子个数来判断当前点的奇偶性&#x…

.netcore 分布式事务CAP2.6之控制台使用

上一编.netcore 分布式事务CAP2.6 快速入门 讲了cap2.6的快速入门&#xff0c;这次我们来讲讲在控制台中如何使用cap2.6。因为cap2.6的内存模式目前已经可以使用了&#xff0c;相关组件已经更新&#xff0c;所以这次我们以简单的内存模式为例。1&#xff1a;创建项目创建一个名…

TestinPro应用与DevOps之路

文 | 中国农业银行软件研发中心 系统支持部 王晓昕 程伟静 胡莉莉Testin Pro&#xff08;云测平台&#xff09;是一款移动端自动化测试平台工具&#xff0c;帮助用户实现移动端测试自动化&#xff0c;是一套设备统一调配、软硬件一体化的移动端测试方案。Testin Pro具有在线录制…

通过Service访问应用 (2)

目录 通过NodePort Service在外部访问集群应用 通过LoadBalancer Service在外部访问集群应用 Microsoft SQL Server数据库部署 为了便于理解和学习&#xff0c;请先阅读上一篇《通过Service访问应用 &#xff08;1&#xff09;》再继续学习本篇内容。通过NodePort Service在外…

【A】兼容Core3.0后 Natasha 的隔离域与热编译操作。

文章转载授权级别&#xff1a;A 预计阅读时间&#xff1a;15分钟一、 2.0预览版本增加了哪些功能大部分为底层的升级优化&#xff0c;例如&#xff1a;引擎兼容 Core3.0优化编译流程&#xff0c;增加编译前语法检测及日志&#xff0c;统一采用流加载方式在 Vito 的建议…

.NET Core 使用 K8S ConfigMap的正确姿势

背景ASP.NET Core默认的配置文件定义在 appsetings.json和 appsettings.{Environment}.json文件中。这里面有一个问题就是&#xff0c;在使用容器部署时&#xff0c;每次修改配置文件都需要重新构建镜像。当然你也可能会说&#xff0c;我的配置文件很稳定不需要修改&#xff0c…

2019-03-22-算法-进化(环形链表)

题目描述 给定一个链表&#xff0c;判断链表中是否有环。 为了表示给定链表中的环&#xff0c;我们使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;索引从 0 开始&#xff09;。 如果 pos 是 -1&#xff0c;则在该链表中没有环。 示例 1&#xff1a; 输入&#xf…

ASP.NET Core on K8S深入学习(9)Secret Configmap

本篇已加入《.NET Core on K8S学习实践系列文章索引》&#xff0c;可以点击查看更多容器化技术相关系列文章。01—Secret关于Secret在应用启动过程中需要一些敏感信息&#xff0c;比如数据库用户名、密码&#xff0c;如果直接明文存储在容器镜像中是不安全的&#xff0c;K8S提供…

.NET Core 学习资料精选:进阶

2019.09月就要正式发布.NET 3.0了&#xff0c;对于前一篇博文《.NET Core 学习资料精选&#xff1a;入门》大家学的可还开心&#xff1f;这是本系列的第二篇文章&#xff1a;进阶篇&#xff0c;喜欢的园友速度学起来啊。对于还在使用传统.NET Framework 框架的园友&#xff0c;…