SonarQube & SonarQube Scanne

作者: 纳爱斯 | 来源:发表于2017-05-20 00:06 被阅读1539次

    CentOS MySQL SonarQube SonarQube Scanner

    SonarQube 简介

    • SonarQube 能够提供对代码的一整套检查扫描和分析功能,拥有一套服务器端程序,然后再通过客户端或者别的软件的插件的形式完成对各开发环境和软件的支持。

    • 对编程语言的支持非常广泛,包括 C、C++、Java、Objective C、Python、JavaScript、PHP、C#、Swift、Erlang、Groovy 等众多语言
      提供了对 HTML、CSS、JSON、XML、CSV、SQL、JSP/JSF 等类型的文档的支持

    • 提供了以 FindBugs、PMD、CheckStyle 方式执行代码分析和测试检查的功能

    • 登录认证方式支持 LDAP、Bitbucket、Azure Active Directory(AAD)、Crowd 等方式

    • 提供了优美的 3D 视图方式下查看代码分析和测试结果报告

    SonarQube 能带来什么???

    ➢ 糟糕的复杂度分布:文件、类、方法等,如果复杂度过高将难以改变,这会使得开发人员难以理解它们,且如果没有自动化的单元测试,对于程序中的任何组件的改变都将可能导致需要全面的回归测试

    ➢ 重复:显然程序中包含大量复制粘贴的代码是质量低下的,sonar 可以展示源码中重复严重的地方

    ➢ 缺乏单元测试:sonar 可以很方便地统计并展示单元测试覆盖率

    ➢ 没有代码标准:sonar 可以通过 PMD、CheckStyle、Findbugs 等等代码规则检测工具规范代码编写

    ➢ 没有足够的或者过多的注释:没有注释将使代码可读性变差,特别是当不可避免地出现人员变动时,程序的可读性将大幅下降。而过多的注释又会使得开发人员将精力过多地花费在阅读注释上,亦违背初衷

    ➢ 潜在的 bug:sonar 可以通过 PMD、CheckStyle、Findbugs 等等代码规则检测工具检测出潜在的 bug

    SonarQube 环境搭建

    Tip:我这里安装的 SonarQube 6.3.1,需要 JDK 1.8 以上的版本,MySQL 版本建议 5.6 以上,若 MySQL 版本高于 5.6 可以直接进行第四步

    • 第一步:升级数据库
      重要的事情说三遍:先备份旧数据库,先备份旧数据库,先备份旧数据库,然后再删除,再安装新的
      安装包下载之后,按照以下步骤操作
    验证MD5:md5sum mysql57-community-release-el6-9.noarch.rpm    
            验证包的MD5,务必要和官方给出的保持一致,确认无误才行
    
    接着执行:rpm -ivh mysql57-community-release-el6-9.noarch.rpm
            -i 是安装指令install的简写,-v是详尽模式verbose的简写,-h是打印要安装的包的Hash码(与-v组合使用)
    
            开始安装MySQL的发布包,这个过程会瞬间完成。输出类似于下面这样的信息:
            Preparing...                ########################################### [100%]
               1:mysql57-community-relea########################################### [100%]
    
    • 第二步:执行yum install -y mysql-community-client mysql-community-server(这个过程会需要一些时间)

    • 第三步:安装完成之后,打开/etc/my.cnf文件,在[mysqld]节点下增加如下两行👇,然后重新启动mysqld服务

    character_set_server=utf8  
    init_connect='SET NAMES utf8'
    
    FAQ:
    1.如果启动' mysqld '服务时卡在Installing validate password plugin:这个步骤过不去,可以先中止这个过程,解决方案如下:
        ➯ vim /etc/my.cnf
        ➯ 在[mysqld]这个节下面添加一行内容`validate_password=off`
          这是临时禁止密码验证插件,可以在以后需要的时候再配置即可。
          此时的数据库已经正常工作了,但是我们还不能使用
        ➯ vim /var/log/mysqld.log,找到类似于下面的内容:
          A temporary password is generated for root@localhost: -?i;XHTuh5eH
          这里的' -?i;XHTuh5eH '就是临时密码,
        ➯ 重新启动mysqld服务之后,输入:mysql -u root -p,回车,之后输入临时密码
        ➯ 成功登录到MySQL,此时再使用命令:alter user 'root'@'localhost' identified by '123';
          更新root用户的默认密码,5.6以后的版本安全机制增强了,临时密码只允许登录,不允许操作数据库,所以必须更改。
    2.忘记登录密码,解决方案如下:
        ➯ vim /etc/my.cnf
        ➯ 在文件中`[mysqld]`下添加skip-grant-tables,如图所示:
        ➯ 登录mysql:mysql -uroot -p (直接点击回车,密码为空)
        ➯ 设置用户密码:update mysql.user set authentication_string=PASSWORD('123456') where user='root';
        ➯ 更新privilige:flush privileges;
        ➯ 退出:exit
        ➯ 删除在my.cnf文件中`skip-grant-tables`
        ➯ 重启:service mysqld restart
        -------------------------------------------------------------------------------------------------------------------------------------------
        | 第2个问题按照上面设置之后如果在登陆之后操作之后的时候,遇见如下错误👇
        | `ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.` 
        | 解决方法:alter user 'root'@'localhost' IDENTIFIED with mysql_native_password AS '*0D3CED9BEC10A777AEC23CCC353A8C08A633045E';
        | 当之后重新设置密码时,遇见如下错误👇
        | `[ERROR 1819 (HY000): Your password does not satisfy the current policy requirements]`
        | 解决方法:输入 set global validate_password_policy=0;
        | 之后在设置密码就OK了,命令见`FAQ 2`设置用户密码,然后更新privilige
        | (正如上文所说,MySQL 5.6之后安全机制增强了,所以导致5.6之后的设置密码方式与之前不一样)
    
    • 第四步:创建sonar数据库及sonar用户及设置用户权限
    ➯ 创建数据库:
        CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
    ➯ 创建SonarQube Server访问数据库的用户:
        CREATE USER 'sonar' IDENTIFIED BY 'sonar';
    ➯ 配置SonarQube Server访问数据库用户的权限
        GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar';
        GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar';
    ➯ 更新权限:flush privileges;
     -------------------------
     Tip:
          flush privileges 命令本质上的作用是将当前user和privilige表中的用户信息/权限设
    置从mysql库(MySQL数据库的内置库)中提取到内存里。MySQL用户数据和权限有修改后,希望在
    "不重启MySQL服务"的情况下直接生效,那么就需要执行这个命令。通常是在修改ROOT帐号的设置
    后,怕重启后无法再登录进来,那么直接flush之后就可以看权限设置是否生效,而不必冒太大风险
    
    • 第五步:更改SonarQube配置文件,打开SonarQube下的conf/sonar.properties,如下图👇
    sonar.properties
    取消注释,并按照如下图👇所示,填写内容,其中sonar.jdbc.url这一行只要取消注释就可以
    sonar.properties
    • 第六步:进入SonarQube目录下的/bin/linux-x86-64运行:nohup bash sonar.sh start &
      Tip:nohup command &表示将进程放置后台运行,而对于linux-x86-64这个文件夹是根据你当前安装SonarQube的系统决定的,是哪个系统就进那个文件夹
    • 第七步:访问http://127.0.0.1:9000,如果不是本机就输入http://IP:9000接着你会看到如下图所示👇
    SonarQube
    接着点击Log in,默认账号:admin,密码:admin Log in

    登录之后,按如下操作安装中文插件

    install Chinese Pack Restart 大功告成

    SonarQube Scanner 配置

    • 准备工作

    • 第一步:下载之后解压zip包,之后进入该目录的conf文件夹下,打开文件sonar-scanner.properties,如下图所示👇

    sonar-scanner.properties

    在文件中,将下面一行取消注释即可

    # 如果是远程的话,请将localhost修改为远程机器的IP地址
    sonar.host.url=http://localhost:9000
    
    sonar-scanner.properties
    • 第二步:到工程根目录下新建文件sonar-project.properties,文件内容如下👇,文件中的参数配置,参考Sonar Analysis Parameters这篇文章
    # 指定SonarQube instance必须是唯一的
    sonar.projectKey=Jacoco
    # 设置SonarQube UI显示的名称 
    # PS:有人会问这里的名称是否可以是中文名称,我在网上搜索了好多资料都说是不可以的(至少我看到的资料都是)
    #     后来自己尝试了一下,答案是可以写成中文的,但是要换一种方式,比如你想把项目名称命名为“测试”,
    #     那么在这里就要写成“\u6d4b\u8bd5”,那么下面这个参数就应该这样写“sonar.projectName= \u6d4b\u8bd5”,
    #     说白了就是将中文转成Unicode
    sonar.projectName= Jacoco
    sonar.projectVersion=1.0
    sonar.language=java
    # 指定src和classes文件夹位置,当然也可以是全路径,如果是当前工程根目录下用“.”表示也可以,比如“sonar.sources=.”
    sonar.sources=src
    sonar.java.binaries=target
    # 下面的这两个参数作用是相同的,因为有时我们需要指定某个文件夹或者忽略某个文件夹
    # sonar.inclusions=src1/**,src3/**
    # sonar.exclusions=src2/**,src4/**
    # 源码编码,默认是系统编码
    sonar.sourceEncoding=UTF-8
    # Set jacoco Configuration
    # 指定代码覆盖率工具
    sonar.core.codeCoveragePlugin=jacoco
    # 指定exec二进制文件存放路径
    sonar.jacoco.reportPaths=[yourPath/]jacoco.exec
    # 以下属性可选择性加,当然也可以不加
    sonar.dynamicAnalysis=reuseReports
    sonar.jacoco.reportMissing.force.zero=false
    

    Tip:可以将这里的知识结合Jacoco Code Coverage结合这篇的中的Demo工程实践一下,当然如果同时想要分析代码覆盖率的话你就要在下载Demo工程之后,运行mvn test生成exec二进制文件,并将exec文件的路径补全,当然如果找不到这个文件也不会报错,只是在SonarQube平台上看不到代码覆盖率

    • 第三步:第一和第二步完成之后,进入sonar-scanner-xxxconf目录下,你会发现两个文件sonar-scanner&sonar-scanner-debug,配置一下环境变量,如下所示👇
    export SONAR_SCANNER_HOME=[yourSonarScannerPath/]
    export PATH=$PATH:$SONAR_SCANNER_HOME/bin:PATH
    

    Tip:配置好环境变量之后,source一下使之生效
    然后从终端进入工程根目录,运行sonar-scanner你会看到如下日志👇

    INFO: Scanner configuration file: /Users/zc/Downloads/sonarqube-6.3.1/extensions/plugins/sonar-scanner-3.0.1.733-macosx/conf/sonar-scanner.properties
    INFO: Project root configuration file: /Users/zc/Desktop/jacoco/sonar-project.properties
    INFO: SonarQube Scanner 3.0.1.733
    INFO: Java 1.8.0_121 Oracle Corporation (64-bit)
    INFO: Mac OS X 10.12.4 x86_64
    INFO: User cache: /Users/zc/.sonar/cache
    INFO: Load global settings
    INFO: Load global settings (done) | time=54ms
    INFO: User cache: /Users/zc/.sonar/cache
    INFO: Load plugins index
    INFO: Load plugins index (done) | time=4ms
    INFO: Plugin [l10nzh] defines 'l10nen' as base plugin. This metadata can be removed from manifest of l10n plugins since version 5.2.
    INFO: SonarQube server 6.3.1
    INFO: Default locale: "zh_CN", source code encoding: "UTF-8"
    INFO: Process project properties
    INFO: Load project repositories
    INFO: Load project repositories (done) | time=51ms
    INFO: Load quality profiles
    INFO: Load quality profiles (done) | time=12ms
    INFO: Load active rules
    INFO: Load active rules (done) | time=254ms
    INFO: Load metrics repository
    INFO: Load metrics repository (done) | time=45ms
    WARN: SCM provider autodetection failed. No SCM provider claims to support this project. Please use sonar.scm.provider to define SCM of your project.
    INFO: Publish mode
    INFO: Project key: com.jacoco
    INFO: -------------  Scan JacocoTest
    INFO: Load server rules
    INFO: Load server rules (done) | time=49ms
    INFO: Language is forced to java
    INFO: Initializer GenericCoverageSensor
    INFO: Initializer GenericCoverageSensor (done) | time=0ms
    INFO: Base dir: /Users/zc/Desktop/jacoco
    INFO: Working dir: /Users/zc/Desktop/jacoco/.scannerwork
    INFO: Source paths: src
    INFO: Source encoding: UTF-8, default locale: zh_CN
    INFO: Index files
    INFO: 2 files indexed
    INFO: Quality profile for java: Sonar way
    INFO: Sensor JavaSquidSensor [aemrules]
    INFO: Configured Java source version (sonar.java.source): none
    INFO: JavaClasspath initialization
    WARN: Bytecode of dependencies was not provided for analysis of source files, you might end up with less precise results. Bytecode can be provided using sonar.java.libraries property
    INFO: JavaClasspath initialization (done) | time=8ms
    INFO: JavaTestClasspath initialization
    INFO: JavaTestClasspath initialization (done) | time=0ms
    INFO: Java Main Files AST scan
    INFO: 2 source files to be analyzed
    INFO: Java Main Files AST scan (done) | time=367ms
    INFO: Java Test Files AST scan
    INFO: 2/2 source files have been analyzed
    INFO: 0 source files to be analyzed
    INFO: Java Test Files AST scan (done) | time=0ms
    INFO: Sensor JavaSquidSensor [aemrules] (done) | time=780ms
    INFO: 0/0 source files have been analyzed
    INFO: Sensor SurefireSensor [aemrules]
    INFO: parsing /Users/zc/Desktop/jacoco/target/surefire-reports
    INFO: Sensor SurefireSensor [aemrules] (done) | time=49ms
    INFO: Sensor JaCoCoSensor [aemrules]
    WARN: Property 'sonar.jacoco.reportMissing.force.zero' is deprecated and its value will be ignored.
    INFO: Analysing /Users/zc/Desktop/jacoco/target/coverage-reports/jacoco-unit.exec
    INFO: No information about coverage per test.
    INFO: Sensor JaCoCoSensor [aemrules] (done) | time=58ms
    INFO: Sensor SonarJavaXmlFileSensor [aemrules]
    INFO: Sensor SonarJavaXmlFileSensor [aemrules] (done) | time=0ms
    INFO: Sensor Analyzer for "php.ini" files [php]
    INFO: Sensor Analyzer for "php.ini" files [php] (done) | time=2ms
    INFO: Sensor Zero Coverage Sensor
    INFO: Sensor Zero Coverage Sensor (done) | time=11ms
    INFO: Sensor Code Colorizer Sensor
    INFO: Sensor Code Colorizer Sensor (done) | time=0ms
    INFO: Sensor CPD Block Indexer
    INFO: org.sonar.scanner.cpd.deprecated.JavaCpdBlockIndexer@6cf047cf is used for java
    INFO: Sensor CPD Block Indexer (done) | time=17ms
    INFO: No SCM system was detected. You can use the 'sonar.scm.provider' property to explicitly specify it.
    INFO: Calculating CPD for 2 files
    INFO: CPD calculation finished
    INFO: Analysis report generated in 66ms, dir size=30 KB
    INFO: Analysis reports compressed in 8ms, zip size=11 KB
    INFO: Analysis report uploaded in 19ms
    INFO: ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/dashboard/index/com.jacoco
    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/api/ce/task?id=AVwlSI7NKkvX7ZORxf9W
    INFO: Task total time: 2.584 s
    INFO: ------------------------------------------------------------------------
    INFO: EXECUTION SUCCESS
    INFO: ------------------------------------------------------------------------
    INFO: Total time: 13.546s
    INFO: Final Memory: 50M/306M
    INFO: ------------------------------------------------------------------------
    

    接下来我们回到之前搭建好的SonarQube平台,看一下检测的结果,效果展示如下图👇

    说明一下:
       上文运用的Sonar Sanner只是实现代码检测方式的其中之一而已,当然还有其它做法,比如直接在
    pom.xml文件中引用sonar插件,但是我这里考虑的是与Jenkins做成持续集成,如果我选择在项目中添
    加sonar-project.properties文件,这样能更方面与Jenkins结合
    
    

    到这里基本上就结束了,下面就是将Jenkins与SonarQube集成,详见:Jenkins + SonarQube & SonarQube Scanner

    如在阅读或者实践过程中遇到问题,欢迎下方留言

    相关文章

      网友评论

      • 大梦一場的黎峻滔伯伯:目前我exec文件已经可以生成了,但是在scanner进行扫描和生成报告的时候,报了不少错,其中有找不到java文件的,类似这种:ERROR - Class not found: org.slf4j.Logger
        也有找不到class文件的,类似这种: Class 'org/mybatis/spring/SqlSessionTemplate' is not accessible through the ClassLoader

        我的java配置在/src/main/java
        class配置在/target/classes

        实在不清楚是什么原因了,麻烦帮忙看一下~
        大梦一場的黎峻滔伯伯:@纳爱斯 嗯嗯,这个我已经看过了,今天研究了一下午,我用mvn sonar插件命令那种方式已经可以生成覆盖率报告了,但是jenkins的sonar插件还是会有一些error和warn。我目前是把项目的java和class文件都拷贝到/export/lijuntao下的source和class文件中的,build是成功了的,只不过一直提示某些class is not accessible,这让人很烦,我也检查过我的class文件夹了,那些提示找不到的在文件夹里确实是有的

        sonar.projectKey=XXXXXX
        #Set through <version> when using Maven.
        sonar.projectVersion=1.0-SNAPSHOT
        #jenkins 设置SonarQube UI显示的名称,别用中文
        sonar.projectName=XXXXXXXXX
        sonar.language=java
        #代码所在路径
        sonar.projectBaseDir=/export/lijuntao/source
        #指定source文件路径
        sonar.sources=/export/lijuntao/source

        #指定class文件路径
        sonar.java.binaries=/export/lijuntao/class

        # 源码编码,默认是系统编码
        sonar.sourceEncoding=UTF-8

        #Set jacoco Configuration
        #Code coverage tool
        sonar.java.coveragePlugin=jacoco
        #Path to the JaCoCo report file containing coverage data by unit tests. The path may be absolute or relative to the project base directory
        sonar.jacoco.reportPath=./jacoco.exec
        sonar.jacoco.itReportPath=./jacoco.exec
        #sonar.jacoco.reportMissing.force.zero
        sonar.jacoco.reportMissing.force.zero=false
        纳爱斯:看看这个地址:https://docs.sonarqube.org/display/PLUG/Java+Plugin+and+Bytecode
        纳爱斯:@大梦一場的黎峻滔伯伯 把你sonar-project.properties文件的配置发我看一下吧 我猜测是没有指定class文件的存放位置
      • d1b0f55d8efb:这都是在Mac下部署的,还是linux
        纳爱斯:我是在Linux上部署的,Mac上其实是一样的

      本文标题:SonarQube & SonarQube Scanne

      本文链接:https://www.haomeiwen.com/subject/tpqqxxtx.html