Mark Xu 的博客

记录精彩的程序人生

SonarQube 代码扫描实战

本篇博客主要记录使用 SonarQube 进行代码静态扫描实战过程。

环境安装

在 Jenkins 中项目已经可以跑通的前提下,引入 SonarQube 代码静态扫描,需要安装 SonarQube Server(最新版本 7.3)、Sonar Scanner(最新版本 3.2.0.1227)、SonarQube Scanner for Jenkins 插件。整体安装流程较为简单,但是因环境差异会产生各种小问题,Google 即可。

SonarQube Server 整体安装流程可参考此篇博文,SonarQube Scanner for Jenkins 插件安装可参考此篇博文

代码扫描配置

本次安装过程中,存在的比较大的一个问题就是代码扫描属性配置问题。SonarScanner 扫描属性可以直接在项目根目录下的 sonar-project.properties 文件中进行配置,也可以在 Jenkins 具体项目的设置中进行配置。我这边采用在项目中进行配置,位置如下:

上图中的 Analysis properties 属性是配置关键所在,先来看看 Sonar 官方文档给出的可配置选项:

// 项目 key,需唯一
sonar.projectKey=my:project
// 在 SonarQube 控制台上显示的项目名称和版本号,SonarQube 6.1 之前的版本必须填写这两个选项.
sonar.projectName=My project
sonar.projectVersion=1.0
 
// Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
// This property is optional if sonar.modules is set. 
sonar.sources=.
 
// 源码编码格式
// sonar.sourceEncoding=UTF-8

相关问题整理

Java 版本过低问题

SonarQube 启动报错:

WrapperSimpleApp: Unable to locate the class org.sonar.application.App: java.lang.UnsupportedClassVersionError: org/sonar/application/App : Unsupported major.minor version 52.0

SonarQube Server 调用了 Java 的系统默认版本 1.7,而最新版的 SonarQube 需要 Java1.8 的支持。只需更改 SonarQube Server 目录下 \conf\wrapper.conf 文件,新增如下配置即可:

wrapper.java.command=/data/app/jdk1.8.0_171/bin/java

SonarQube 在异常重启服务器后无法启动问题

启动报错:

INFO  app[][o.s.a.AppFileSystem] Cleaning or creating temp directory /usr/local/sonarqube/sonarqube-7.3/temp

WrapperSimpleApp: Encountered an error running main: java.nio.file.AccessDeniedException: /usr/local/sonarqube/sonarqube-7.3/temp/conf/es/elasticsearch.yml
java.nio.file.AccessDeniedException: /usr/local/sonarqube/sonarqube-7.3/temp/conf/es/elasticsearch.yml
        at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
        at sun.nio.fs.UnixFileSystemProvider.implDelete(UnixFileSystemProvider.java:244)
        at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)

出现此问题原因是 temp 目录异常关机时出现问题,因此只需要删除对应的 temp 目录即可,删除时注意目录权限。

SonarQube 不能以 root 用户启动问题

启动报错:

java.lang.RuntimeException: can not run elasticsearch as root

出现此问题的原因是 elasticsearch 不允许使用 root 用户直接运行,因此创建新用户即可:

$ adduser sonarUSer
$ passwd sonarUser
$ chown -R sonarUser:sonarUser sonarqube-7.3
$ ./sonar.sh start

SonarQube 中文插件

https://github.com/SonarQubeCommunity/sonar-l10n-zh 查找适用于当前 SonarQube 版本的中文插件并下载,放入 SonarQube 目录 sonarqube-5.6\extensions\plugins 下,重启 SonarQube 即可。

代码扫描报错问题

代码扫描时报错如下:

java.lang.IllegalStateException: No files nor directories matching 'target/'

此问题是由于 sonar-project.properties 文件配置错误问题,一般问题都是出现在相对路径的配置上。

附上本人的相关配置,Android 项目配置如下:

sonar.projectKey=jianzhimao
sonar.projectName=CICDTese
sonar.projectVersion=1.0
sonar.sourceEncoding=UTF-8
sonar.modules=java-module

java-module.sonar.projectName=Java Module
java-module.sonar.language=java
java-module.sonar.sources=app/src/main/java
java-module.sonar.projectBaseDir=.
sonar.java.binaries=app/build/intermediates/classes

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# This property is optional if sonar.modules is set. 
sonar.sources=.
sonar.test.inclusions=**/*androidTest*/**,**/src/main/java/**
#sonar.test.exclusions=**/src/main/java/**
sonar.exclusions=**/*androidTest*/**,**/src/main/java/**
#sonar.inclusions=**/src/main/java/**

Java 项目配置如下:

sonar.projectKey=jianzhimao
sonar.projectName=JzmaoBackend_dev2
sonar.projectVersion=1.0
sonar.language=java
sonar.sources=$WORKSPACE/src
sonar.java.binaries=$WORKSPACE/target/test-classes/ 

关于 SonarQube 项目的 inclusions 和 exclusions 目录,仍有问题未解决,此处仅供参考。

MySQL max_allowed_packet 设置过小引起的上传扫描日志文件失败问题

日志如下:

Failed to upload report - 500: An error has occurred. Please contact your administrator

经排查,原来是 MySQL 的 max_allowed_packet 属性设置过小引起的,MySQL 会根据配置文件限制 Server 接受的数据包大小,默认为 4M,而生成的代码扫描日志文件超过了 4M,所以上传失败。

查看当前设置:

show VARIABLES like '%max_allowed_packet%';

修改 my.cnf 文件(/etc/ 目录下)来更改设置:

max_allowed_packet=20M

注意!需要重启 MySQL 服务和 SonarQube 服务后,设置才会生效。

参考文档

使用 Jenkins 与 Sonar 集成对代码进行持续检测

留下你的脚步