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插件自带构建失败功能。当所有扫描通过了即构建成功,允许合并。
关注我的公众号