zoukankan      html  css  js  c++  java
  • 【Jenkins使用之七】代码质量之静态代码分析

    一、常用Java静态代码分析工具的分析与比较
    Java 静态代码分析(static code analysis)工具能够在代码构建过程中帮助开发人员快速、有效的定位代码缺陷并及时纠正这些问题,从而极大地提高软件可靠性并节省软件开发和测试成本。
    常用的有Checkstyle、FindBugs、PMD,他们各有侧重,目前PMD集成阿里的p3c比较流行。

    1、PMD
    PMD是一款采用BSD协议发布的Java程序代码检查工具。该工具可以做到检查Java代码中是否含有未使用的变量、是否含有空的抓取块、是否含有不必要的对象等。该软件功能强大,扫描效率高,是Java程序员debug的好帮手。
    PMD附带了许多可以直接使用的规则,利用这些规则可以找出Java源程序的许多问题,常见的类型如下:

    ①潜在的bug:空的try/catch/finally/switch语句
    ②未使用的代码:未使用的局部变量、参数、私有方法等
    ③可选的代码:String/StringBuffer的滥用
    ④复杂的表达式:不必须的if语句、可以使用while循环完成的for循环
    ⑤重复的代码:拷贝/粘贴代码意味着拷贝/粘贴bugs
    ⑥循环体创建新对象:尽量不要再for或while循环体内实例化一个新对象
    ⑦资源关闭:Connect,Result,Statement等使用之后确保关闭掉

    此外,用户还可以自己定义规则,检查Java代码是否符合某些特定的编码规范,如集成阿里的p3c。

    参考:静态分析工具PMD

    2、FindBugs

    FindBug 是一款开源的 Java 代码检查工具,遵循 GNU 公共许可协议。它可以检查 Java 类或者 JAR 文件,运行的是 Java 字节码而不是源码,检查原理是:将字节码与一组缺陷模式进行对比来发现可能存在的问题,这些问题包括空指针引用、无限递归循环、死锁等。检查的 bug 类型包括:

    Malicious code vulnerability:恶意代码
    Dodgy code:不符合规范的代码
    Internationalization:国际化相关问题,如错误的字符串转换;
    Bad practice:坏的实践:常见代码错误,序列化错误,用于静态代码检查时进行缺陷模式匹配;
    Multithreaded correctness:多线程的正确性:如多线程编程时常见的同步,线程调度问题;
    Performance:运行时性能问题,如由变量定义,方法调用导致的代码低效问题。
    Correctness:可能导致错误的代码,如空指针引用等;
    Experimental:可能受到的恶意攻击,如访问权限修饰符的定义等;
    Security:安全性

    参考:

    使用 FindBugs-IDEA 插件查找代码中潜在的 BUG

    3、CheckStyle
    CheckStyle作为检验代码规范的插件,除了可以使用配置默认给定的开发规范,如Sun的,Google的开发规范啊,也可以导入像阿里的开发规范的插件。事实上,每一个公司都存在不同的开发规范要求,所以大部分公司会给定自己的check规范,一般导入给定的checkstyle.xml文件即可实现。

    Javadoc 注释:检查类及方法的 Javadoc 注释
    命名约定:检查命名是否符合命名规范
    标题:检查文件是否以某些行开头
    Import 语句:检查 Import 语句是否符合定义规范
    代码块大小,即检查类、方法等代码块的行数
    空白:检查空白符,如 tab,回车符等
    修饰符:修饰符号的检查,如修饰符的定义顺序
    块:检查是否有空块或无效块
    代码问题:检查重复代码,条件判断,魔数等问题
    类设计:检查类的定义是否符合规范,如构造函数的定义等问题

    参考:

    CheckStyle使用

    Eclipse中安装和使用CheckStyle

    4、区别

    参考:

    常用Java静态代码分析工具的分析与比较

    代码质量检测工具FindBugs、PMD和CheckStyle对比

    二、静态代码分析插件集成
    通常这些工具都会提供IDE插件、maven插件、jenkins插件、sonarQube插件。
    也就是说Checkstyle、FindBugs、PMD有:
      针对于开发人员本机的代码检查使用的Eclipse、Idea都有对应的插件;
      针对于构建jenkins、maven也有对应的插件,可以生成测试报告,用于自动化构建,避免开发人员不进行本机检查就上传代码的情况(sonarQube出来之前就是使用maven来生成报告);
      针对于sonarQube代码管理平台既可以用于开发人员检查代码,也可以集成到自动化构建平台生成检查报告。
    注意:为方便在后面的自动化构建中统一,在一个project中事务开发、自动化构建等环节要使用同一种分析工具。

    公司里一般涉及两个环节:

    1、开发环节

    1)开发人员要求使用统一 的IDE(eclipse、Idea),然后安装统一的静态代码检查工具:比如checkStyle检查公司要求的代码规范、PMD或findbugs检查潜在问题代码;

    2)当开发人员开发完成功能后,使用这些IDE集成插件检查代码,并修正插件检测出来的问题;

    3)将代码提交的版本库(git或者svn);

    2、自动构建环节

    公司每天进行代码的全量构建,jenkins要事先安装相应的Checkstyle、FindBugs、PMD插件:

    1)jenkins从版本库主干或分支拉取源代码;

    2)使用maven插件编译;

    3)通过maven调用Checkstyle、FindBugs、PMD插件代码检查,如果检测出来相应问题 则构建失败,并将问题、问题代码提交人发邮件通知相关人员修改。

    以上两个环节出了使用这些插件以外,目前是使用sonarQube代码质量管理平台来检查,sonarQube除了有自身的检查规则以外,也可以集成Checkstyle、FindBugs、PMD插件,然后生成检查报告。

    参考:

    eclipse集成阿里代码规范工具p3c

    Eclipse中安装和使用CheckStyle

    Eclipse 安装FindBugs插件

    Jenkins下配置findbugs、pmd及checkstyle实现代码自动检测 

    三、SonarQube

    SonarQube是一个代码质量数据报告工具,也是代码质量管理平台,相对于Checkstyle、FindBugs、PMD,有更加优秀的图形化界面,以及可以查询出其它软件难以定位到的问题。

    SonarQube可以从以下七个维度检测代码质量:

    (1)不遵循代码标准:SonarQube可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具规范代码编写。
    (2)潜在的缺陷:SonarQube可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具检 测出潜在的缺陷。
    (3)糟糕的复杂度分布:文件、类、方法等,如果复杂度过高将难以改变,这会使得开发人员 难以理解它们, 且如果没有自动化的单元测试,对于程序中的任何组件的改变都将可能导致需要全面的回归测试。
    (4)重复:显然程序中包含大量复制粘贴的代码是质量低下的,sonar可以展示 源码中重复严重的地方。
    (5)注释不足或者过多:没有注释将使代码可读性变差,特别是当不可避免地出现人员变动 时,程序的可读性将大幅下降 而过多的注释又会使得开发人员将精力过多地花费在阅读注释上,亦违背初衷。
    (6)缺乏单元测试:SonarQube可以很方便地统计并展示单元测试覆盖率。
    (7)糟糕的设计:通过SonarQube可以找出循环,展示包与包、类与类之间的相互依赖关系,可以检测自定义的架构规则 通过sonar可以管理第三方的jar包,可以利用LCOM4检测单个任务规则的应用情况, 检测藕合。

    1、SonarQube安装
    SonarQube是一个平台,要部署一个专门的Server应用,然后通过界面来管理和查看。SonarQube服务器主要包括web服务器,基于ElasticSearch的搜索服务器,计算引擎服务器。其中,web服务器,是供开发人员浏览查看代码分析结果,进行相应的配置等。计算引擎服务器主要是处理代码分析报表并将其存储在数据库。SonarQube数据库用来存储配置信息和代码分析报表。

    关于SonarQube没有权威的书籍,只能查看官网文档:https://docs.sonarqube.org/   选择相应版本查看就可以了。

    (1)关于安装jdk、mysql、maven版本

    jdk:jdk1.8
    mysql:要求>=5.6 && < 8.0,默认是H2 embbed 内存类型数据库,用来保存元数据信息,为了长期管理肯定要用持久化数据库,这里选用mysql,当然也可以选择其他的。
    maven:3.6.3

    (2)下载SonarQube CE版本(其他版本收费):http://www.sonarqube.org/downloads/
    SonarQube-7.8依赖Java 8,且支持mysql管理元数据的最后版本,以后的版本需要jdk11且不支持mysql 管理配置元数据。

    (3)解压
    [root@node106 src]# unzip sonarqube-7.8.zip -d /usr/local

    (4)配置
    修改为mysql数据库,url是数据库连接地址,username是数据库用户名,jdbc.password是数据库密码,login是sonarqube的登录名,sonar.password是sonarqube的密码

    [root@node106 conf]# vim /usr/local/sonarqube-7.8/conf/sonar.properties
    sonar.jdbc.url=jdbc:mysql://192.168.0.141:3306/qjfsonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance
    sonar.jdbc.username=gmsd
    sonar.jdbc.password=gmsdtrade
    sonar.sorceEncoding=UTF-8
    sonar.login=admin
    sonar.password=admin

    (5)启动

    #默认端口sonar.web.port=9000 可以修改

    [root@node106 linux-x86-64]# /usr/local/sonarqube-7.8/bin/linux-x86-64/sonar.sh start
    Starting SonarQube...
    Started SonarQube.

    报错:

    1)、org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root
    sonarqube里面有elasticsearch组件,ES不允许使用root启动,新建普通用户启动。

    2)、[2] bootstrap checks failed
    [1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
    [2]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
    修改/etc/security/limits.conf 后面追加如下内容:

    [root@node106 conf]# vim /etc/security/limits.conf
    * soft nofile 65536
    * hard nofile 65536
    * soft memlock unlimited
    * hard memlock unlimited

    3)、[1] bootstrap checks failed
    [1]: max virtual memory areas vm.max_map_count [65536] is too low, increase to at least [262144]

    #修改/etc/sysctl.conf
    [root@node106 logs]# vim /etc/sysctl.conf
    [root@node106 logs]# sysctl -p
    vm.max_map_count = 655360

    #注意修改后重新登录 才能生效

    4)、java.lang.IllegalStateException: Fail to connect to database
    修改mysql允许sonarQube所在的主机访问
    grant all privileges on *.* to root@'%' identified by "123456";

    完全启动需要较长时间:

    (6)安装中文插件
    进入Marketplace查找插件 并进行install

    目前插件市场里提供匹配最新8.4版本的汉化插件,和我安装的7.8版本不匹配,install时会报错:

    我们要下载7.8 对应版本中文插件 sonar-l10n-zh-plugin-1.28.jar,地址:https://github.com/SonarQubeCommunity/sonar-l10n-zh/releases
    然后放入 sonarqube-7.8/extensions/plugins 目录

    [root@node106 plugins]# pwd
    /usr/local/sonarqube-7.8/extensions/plugins
    [root@node106 plugins]# ll
    total 88032
    -rw-r--r-- 1 sonar sonar 224 Jun 17 2019 README.txt
    -rw-r--r-- 1 sonar sonar 287504 Jun 17 2019 sonar-auth-github-plugin-1.5.0.870.jar
    -rw-r--r-- 1 sonar sonar 3388540 Jun 17 2019 sonar-auth-saml-plugin-1.1.0.181.jar
    -rw-r--r-- 1 sonar sonar 4092977 Jun 17 2019 sonar-csharp-plugin-7.14.0.8411.jar
    -rw-r--r-- 1 sonar sonar 7016445 Jun 17 2019 sonar-css-plugin-1.1.0.993.jar
    -rw-r--r-- 1 sonar sonar 1551459 Jun 17 2019 sonar-flex-plugin-2.4.0.1222.jar
    -rw-r--r-- 1 sonar sonar 3903342 Jun 17 2019 sonar-go-plugin-1.1.1.2000.jar
    -rw-r--r-- 1 sonar sonar 1727846 Jun 17 2019 sonar-html-plugin-3.1.0.1615.jar
    -rw-r--r-- 1 sonar sonar 14629 Jun 17 2019 sonar-jacoco-plugin-1.0.1.143.jar
    -rw-r--r-- 1 sonar sonar 8302512 Jun 17 2019 sonar-java-plugin-5.13.0.18197.jar
    -rw-r--r-- 1 sonar sonar 6866969 Jun 17 2019 sonar-javascript-plugin-5.2.1.7778.jar
    -rw-r--r-- 1 sonar sonar 7595999 Jun 17 2019 sonar-kotlin-plugin-1.5.0.315.jar
    -rw-r--r-- 1 sonar sonar 47581 Sep 8 09:53 sonar-l10n-zh-plugin-1.28.jar
    -rw-r--r-- 1 sonar sonar 300503 Jun 17 2019 sonar-ldap-plugin-2.2.0.608.jar
    -rw-r--r-- 1 sonar sonar 5107348 Jun 17 2019 sonar-php-plugin-3.1.1.4762.jar
    -rw-r--r-- 1 sonar sonar 2752193 Jun 17 2019 sonar-python-plugin-1.14.0.3086.jar
    -rw-r--r-- 1 sonar sonar 10036210 Jun 17 2019 sonar-ruby-plugin-1.5.0.315.jar
    -rw-r--r-- 1 sonar sonar 9202024 Jun 17 2019 sonar-scala-plugin-1.5.0.315.jar
    -rw-r--r-- 1 sonar sonar 2622236 Jun 17 2019 sonar-scm-git-plugin-1.8.0.1574.jar
    -rw-r--r-- 1 sonar sonar 7229293 Jun 17 2019 sonar-scm-svn-plugin-1.9.0.1295.jar
    -rw-r--r-- 1 sonar sonar 2239156 Jun 17 2019 sonar-typescript-plugin-1.9.0.3766.jar
    -rw-r--r-- 1 sonar sonar 3576923 Jun 17 2019 sonar-vbnet-plugin-7.14.0.8411.jar
    -rw-r--r-- 1 sonar sonar 2242738 Jun 17 2019 sonar-xml-plugin-2.0.1.2020.jar

    安装完成后需要重启sonarQube:

    2、客户端

    参见官网:Analyzing Source Code
    SonarQube按照代码是否在本地还是托管分为本地分析和远程分析:

      本地分析对应的客户端常用有三种:sonar-scanner、使用maven(gradle)插件、使用IDE插件sonarLint,另还有Ant Task 现在用的少了。

      远程分析对应客户端是集成到jenkins里的sonar-scanner插件;

    (一)本地分析

    第一种客户端:sonar-scanner方式

    SonarQube为代码检查的server,并提供可视化界面;sonar-scanner为client,进行分析并将分析报告并且发送到server中,也就是传统的C/S关系。

     

    使用场景除了java、C++以外,其他语言scala,python,php或者一个项目使用多种语言时通过以下方式使用sonar-scanner(下载地址:https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/),这里使用sonar-scanner-cli-4.2.0.1873-windows.zip。在sonar-scanner早期版本叫sonar-runner注意版本太低会报错:Fail to download libraries from server。

    示例拓扑:
    这里我们将SonarQube服务端安装在192.168.118.106 linux上,然后将sonar-scanner安装在192.168.0.141 win7上,然后使用sonar-scanner扫描win7上工程E:srcsmybatis-3-mybatis-3.5.4里的代码。
    (1)解压sonar-scanner-cli-4.2.0.1873-windows.zip

    (2)配置 连接SonarQube同一个数据库 D:sonar-scanner-cli-4.2.0.1873confsonar-runner.properties

    #Configure here general information about the environment, such as SonarQube server connection details for example
    #No information about specific project should appear here
    
    #----- Default SonarQube server  SonarQube服务端
    sonar.host.url=http://192.168.118.106:9000
    #----- Default source code encoding
    sonar.sourceEncoding=UTF-8

    (3)设置环境变量


    (4)示例工程mybatis-3-mybatis-3.5.4
    在要进行代码分析的项目根目录下,新建sonar-project.properties文件

    #----- Global database settings (not used for SonarQube 5.2+)  数据库用户和密码
    sonar.jdbc.username=root
    sonar.jdbc.password=123456
    #----- MySQL  mysql数据库连接  要和SonarQube服务端使用同一个数据库
    sonar.jdbc.url=jdbc:mysql://192.168.0.141:3306/sonar?useUnicode=true&amp;characterEncoding=utf8
    sonar.login=admin
    sonar.password=admin
    
    # 项目key 保证唯一
    sonar.projectKey=mybatis-3-mybatis-3.5.4
    # 项目名字
    sonar.projectName=mybatis-3-mybatis-3.5.4
    sonar.projectVersion=3.5.4
    sonar.language=java
    sonar.modules=java-module
    
    # sonar.sources是源文件所在的目录 注意如果下面还有css文件会要求安装Node.js
    java-module.sonar.sources=src/main/java
    java-module.sonar.projectBaseDir=.
    # 指定class目录 从sonarQube 4.12开始,sonar将会进行程序的动态检查,不配置sonar.java.binaries属性将会出错
    sonar.java.binaries=target/classes
    # Encoding of the source code. Default is default system encoding
    #sonar.sourceEncoding=UTF-8

    (5)然后在该目录下打开命令运行窗口,执行sonar-scanner命令,分析成功之后显示如下:

    到sonarQube界面查看

    第二种方式:使用maven、gradle扫描方式
    这里展示使用maven两种整合方式,前提项目是maven项目。

    (1)修改$MAVEN_HOME/conf/settings.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    
      <localRepository>E:workspace
    epository</localRepository>
      
      <pluginGroups>
        <pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
      </pluginGroups>
    
      <proxies>
      </proxies>
      
      <servers>
        <server>
        <id>releases</id>
        <username>admin</username>
        <password>Aa123456</password>
        </server>
        <server>
        <id>snapshots</id>
        <username>admin</username>
        <password>Aa123456</password>
        </server>
      </servers>
    
      <mirrors>
        <mirror>
            <id>alimaven</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
      </mirrors>
    
      <profiles>
            <profile>
                <id>sonar</id>
                <activation>
                    <activeByDefault>true</activeByDefault>
                </activation>
                <properties>
                    <sonar.host.url>
                      http://192.168.118.106:9000
                    </sonar.host.url>
                </properties>
            </profile>
      </profiles>
    </settings>

    (2)到Maven项目的根目录执行如下命令,即可使用SonarQube分析项目
    方式一:直接在含有pom.xml的目录执行分析

    mvn clean verify sonar:sonar -Dmaven.test.skip=true

    方式二:多模块情况下 先执行install 确保代码最新

    mvn clean install -Dmaven.test.skip=true

    #然后执行分析 注意需要添加-Dsonar.java.binaries参数

    mvn sonar:sonar

    方式三:指定sonar的插件版本

    mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar

    建议可以在项目的pom.xml指定sonar-maven-plugin插件版本

    <build>
      <pluginManagement>
        <plugins>
          <plugin>
            <groupId>org.sonarsource.scanner.maven</groupId>
            <artifactId>sonar-maven-plugin</artifactId>
            <version>3.6.0.1398</version>
          </plugin>
        </plugins>
      </pluginManagement>
    </build>

    第三中方式:使用IDE插件sonarLint

    这里以idea使用sonarLint举例,注意这种方式检查报告旨在idea里查看,sonaQube里看不到

    (1)安装插件

    插件里搜索sonarLint 然后install

    使用方式(一)

    (2)sonarLint全局配置 配置sonarQube服务器

    (3)项目设置

    SonarLint-->Project Setting配置选项卡中配置项目信息,勾选Binding project to  SonarQube / SonarCloud,在Connection下拉框中选中刚刚配置好的服务链接,在project选项中点击Search in list选择相应的项目,点击OK;

    注意这种方式是查询工程下面有sonar-project.properties的工程

    (4)扫描后查看报告

    使用方式(二)

    (1)在需要进行代码分析的项目上点击右键,依次选择:AnaLyze—> AnaLyze with SonarLint(或者再SonarLint报告选项卡中点击AnaLyze All Project Files图标)在弹出对话框中点击Preceed,等待项目代码分析完毕;
    (2)代码分析完毕后,在“SonarQube Report”选项卡中会显示代码分析结果,可对单个文件展开,显示该文件中的各个问题,单击某一条结果,可在右侧Rule选项卡中看到对问题的详细描述,双击某一条记录,可以快速跳转至该条结果对应的代码的位置;
    (3)SonarLint插件默认是自动进行代码检查,但是为了保证代码检查结果的实时性和有效性,在每完成一定数量的代码以后,我们就对代码进行分析。

     (二)远程分析-整合jenkins

     

    3、界面使用教程

    参考:SonarQube使用介绍

     

    sonarQube参考:

    官网文档
    eclipse安装sonarLint插件

    SonarQube的安装、配置与使用

    SonarQube7.3安装和使用说明

    sonarqube简介+架构+搭建+不同语言详细用法

  • 相关阅读:
    [原创] Laravel 启动流程
    修改电脑的TTL返回值
    Apache启动错误解决方法
    RemodelanyWhere11.0.2673版本下载
    函数指针
    指针与数组
    青蛙跳台阶
    旋转数组的最小数字
    对大量人的年龄排序
    泛型算法一
  • 原文地址:https://www.cnblogs.com/cac2020/p/13677271.html
Copyright © 2011-2022 走看看