Java代码质量检查checkstyle, pmd, cpd, p3c,findbugs, jacoco, sonarquebe以及和Jenkins集成

概述

又搞一边质量扫描插件,之前做过一遍,然后后面各种忽略,然后就放弃了,所以,应该寻找一种方法,循序渐进的实施。本次将实施一个基本的打包扫描方案,包含

  • checkstyle 固定团队编码风格,固定命名风格以及换行风格等,原型配置出资googlestyle, 修改缩进为4个字符(原型是2个)
  • surefile test report Junit Test结果报告
  • JaCoCo test coverage 代码测试覆盖率插件
  • 阿里巴巴Java代码扫描插件P3C(PMD)
  • cpd 重复代码扫描
  • Findbugs 通用Java bug检查
  • Sonar Quabe 一站式代码质量审查平台

1. Maven pom插件安装

现有完整的代码demo: https://github.com/Ryan-Miao/code-quality-verify-demo
具体插件内容,查看 https://github.com/Ryan-Miao/code-quality-verify-demo/blob/master/pom.xml

这里大概叙述下配置原理。首先,maven构建生态分build和report,而build又分verify, compile, test, install等生命周期。我们的插件就是基于这几个概念而产生作用的。

先说report插件,位于reporting目录下,主要是在执行mvn site的时候生成各种html report,这里绑定了想要生成各种report的的插件配置。生成的report文件最终位于target/site。

然后是build插件,在构建过程中发生作用。这里可以绑定插件执行到构建过程,比如verify, 当执行install的时候,我们插件就会执行。考虑为了查看report,这里就不绑定生命周期,而是直接通过执行goal的方式来检查。

需要注意的是:

1.Jacoco的覆盖率,目前只配置了全局行覆盖和分支覆盖,不添加阈值则为0,修改阈值实现覆盖率的控制。可以过滤不需要扫描的文件,比如生成的java文件。
2.checkstyle,这个读取我们自定义的checkstyle的配置,后期在使用过程中修改完善程我们自己的配置方案。可以过滤不需要扫描的文件,比如生成的java文件。
3.阿里巴巴Java规范,这个是PMD扫描,但移除了PMD自带的n条规则,只执行阿里的规则,可以过滤不需要扫描的文件,比如生成的java文件。
4.findbugs,指定了配置文件,里面可以配置忽略的文件和bug类型。当然,也可全局配置。

在代码里通过注解或者注释忽略扫描:

1.1 checkstyle忽略

忽略单独的代码模块,比如spring security的配置

核心是添加忽略方案: https://checkstyle.sourceforge.io/config_filters.html

    <module name="TreeWalker">
        <module name="SuppressionCommentFilter">
        </module>
//CHECKSTYLE:OFF
public void someMethod(String arg1, String arg2, String arg3, String arg4) {
//CHECKSTYLE:ON

忽略匹配正则

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <configLocation>config/checkstyle/google-checks-6.18.xml</configLocation>
        <consoleOutput>true</consoleOutput>
        <encoding>UTF-8</encoding>
        <consoleOutput>true</consoleOutput>
        <skip>false</skip>
        <failsOnError>false</failsOnError>
        <linkXRef>true</linkXRef>
        <violationSeverity>error</violationSeverity>
        <!--<includes>**/TestController.java</includes>-->
        <excludes>**/generated/**.java</excludes>
        <excludes>**/**Vo.java</excludes>
    </configuration>
</plugin>

1.2 P3C阿里Java扫描PMD忽略

阿里Java扫描插件使用的PMD来实现,对于某些类不想执行扫描,可以在类上添加注解

@SuppressWarnings("PMD")

也可以直接在excludes里配置

<excludes>
    <exclude>**/*Bean.java</exclude>
    <exclude>**/generated/**.java</exclude>
</excludes>

1.3 FindBugs扫描忽略

FindBugs有些检查我们不想改,比如总是判定Date类是可变的。事实上,我们应该都切换为LocalDate或LocalDateTime,但总有遗留代码采用Date,此时可以忽略扫描

修改配置文件https://github.com/Ryan-Miao/code-quality-verify-demo/blob/master/config/findbugs/findbugs-exclude.xml,

比如正则匹配

<Match>
    <Class name="~.*\.entity\..*" />
  </Match>
  <Match>
    <Class name="~.*\.vo\..*" />
  </Match>

还可以:

<dependency>
    <groupId>com.google.code.findbugs</groupId>
    <artifactId>annotations</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.google.code.findbugs</groupId>
    <artifactId>jsr305</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

然后:


    @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
        value = {"MT_CORRECTNESS", "STYLE"},
        justification = "I know what I'm doing")
    public JdbcTemplate get(String datasourceName) {
        JdbcTemplate jdbcTemplate = TEMPLATE.get(datasourceName);
        if (jdbcTemplate == null) {
            synchronized (this) {
                if (jdbcTemplate == null) {
                    jdbcTemplate = createTemplate(datasourceName);
                    TEMPLATE.put(datasourceName, jdbcTemplate);
                }

                return jdbcTemplate;
            }
        }

        return jdbcTemplate;
    }

2 生成report

上面的pom配置后,执行mvn install site即可生成各种报告

阿里Java检查报告:

checkstyle编码规范报告:

有时候你会发现会爆出这个问题Skipping JaCoCo execution due to missing execution data file,大多数原因是因为没有编译测试类

3 检查阈值

site命令会生成对应的report,但实际开发中,我们会期望出现错误时停止构建,提醒开发者修复问题。bug发现的越早,修复的成本越低。那么,就需要给各个扫描插件设定失败阈值。

3.1Checkstyle设定失败

我们可以选择把checkstyle:check绑定到verify的生命周期上,这样工程师每次变异都会扫描,当出现不符合规范的code style就会编译失败。也可以在检查的时候手动执行一下check。最终,我选择了手动check方案。

 mvn checkstyle:check 

3.2 阿里巴巴Java扫描设定失败

mvn pmd:check

3.3 Findbugs 发现bug失败

findbugs:check

4 Jenkins集成

代码质量不能靠个人素质来维护,而是通过完善的流程制度来保障。我们的代码开发最终都要merge到开发分支。我们只要卡住合并时的代码质量就可以了。规定:当代码合并到dev或者master等保护分支时,CI构建必须success,否则不允许合并分支。

集成Jenkins和Gitlab,添加Merge-Request/Pull-Request扫描任务,当发起Pull Request后自动Jenkins构建,并将构建结果写回Gitlab。

我们使用Jenkins pipeline来配置任务,编写Jenkinsfile
https://github.com/Ryan-Miao/code-quality-verify-demo/blob/master/Jenkinsfile

当任务构建时,我们会生成报告,然后,检查是否通过了扫描。

我们使用Jenkins Warnings Next Generation插件

该插件也提供了qualityGates来根据扫描结果中断构建,但为了保证配置一致性,我采用maven插件自带构建失败功能。当所有扫描通过了即构建成功,允许合并。

posted @ 2019-06-14 16:41  Ryan.Miao  阅读(5750)  评论(0编辑  收藏  举报