记录Gradle中Checkstyle和Spotbugs的使用
介绍
Checkstyle 是一个开发工具,用于帮助程序员编写符合编码标准的 Java 代码。它自动化了检查 Java 代码的过程,使人们免于承担这项枯燥(但重要)的任务。这使得它成为希望实施编码标准的项目的理想选择。
SpotBugs 是一个在 Java 程序中发现 bug 的程序。它寻找“ bug 模式”的实例ーー可能是错误的代码实例。
使用
- 项目目录结构:
projectRoot
| .
| gradle
| | libs.versions.toml
| buildSrc
| | build.gradle
| | settings.gradle
| | src
| | main
| | groovy
| | check.gradle
| config
| | checkstyle
| | | checkstyle.xml
| | findbugs
| | exclude.xml
- Gradle版本管理
projectRoot/gradle/libs.versions.toml
[versions]
spotbugs-gradle-plugin= "5.0.13"
[libraries]
spotbugs-gradle-plugin = { module = "com.github.spotbugs.snom:spotbugs-gradle-plugin", version.ref = "spotbugs-gradle-plugin" }
projectRoot/buildSrc/setting.gradle
dependencyResolutionManagement {
versionCatalogs {
libs {
from(files("../gradle/libs.versions.toml"))
}
}
}
projectRoot/buildSrc/build.gradle
plugins {
id 'groovy-gradle-plugin'
}
repositories {
gradlePluginPortal()
}
dependencies {
implementation libs.spotbugs.gradle.plugin
}
- CheckStyle和Spotbugs约束
projectSrc/buildSrc/src/main/groovy/check.gradle
plugins {
// checkstyle插件
id 'checkstyle'
// spotbugs 插件
id 'com.github.spotbugs'
}
dependencies {
spotbugsSlf4j group: 'org.slf4j', name: 'slf4j-api', version: '1.8.0-beta4'
spotbugsSlf4j group: 'org.slf4j', name: 'slf4j-simple', version: '1.8.0-beta4'
}
spotbugs {
// 是否显示堆栈
showStackTraces = true
// 查找器
omitVisitors = [ 'FindNonShortCircuit' ]
// 生产报告的目录
reportsDir = file("$buildDir/spotbugs")
// 包含匹配的文件
File includeFile = new File("$rootDir/config/findbugs/include.xml")
if (includeFile.exists()) {
includeFilter = file("$rootDir/config/findbugs/include.xml")
}
// 排除匹配的文件
File excludeFile = new File("$rootDir/config/findbugs/exclude.xml")
if (excludeFile.exists()) {
excludeFilter = file("$rootDir/config/findbugs/exclude.xml")
}
// 使用最大堆
maxHeapSize = '1g'
}
// spotbugsMain 任务配置
spotbugsMain {
reports {
// 报告形式使用html形式
html {
required = true
// 文件输出位置
outputLocation = file("$buildDir/reports/spotbugs/main/spotbugs.html")
// 样式形式
stylesheet = 'fancy-hist.xsl'
}
}
}
// spotbugsTest 任务配置, 如上
spotbugsTest {
reports {
html {
required = true
outputLocation = file("$buildDir/reports/spotbugs/main/spotbugs.html")
stylesheet = 'fancy-hist.xsl'
}
}
}
- CheckStyle和SpotBugs配置
-
CheckStyle配置
该配置使用的是Sun的checkstyle规范,当然你也可以根据配置使用其他的。
config/checkstyle/checkstyle.xml
<?xml version="1.0"?> <!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd"> <!-- Checkstyle configuration that checks the sun coding conventions from: - the Java Language Specification at https://docs.oracle.com/javase/specs/jls/se11/html/index.html - the Sun Code Conventions at https://www.oracle.com/java/technologies/javase/codeconventions-contents.html - the Javadoc guidelines at https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html - the JDK Api documentation https://docs.oracle.com/en/java/javase/11/ - some best practices Checkstyle is very configurable. Be sure to read the documentation at https://checkstyle.org (or in your downloaded distribution). Most Checks are configurable, be sure to consult the documentation. To completely disable a check, just comment it out or delete it from the file. To suppress certain violations please review suppression filters. Finally, it is worth reading the documentation. --> <module name="Checker"> <!-- If you set the basedir property below, then all reported file names will be relative to the specified directory. See https://checkstyle.org/config.html#Checker <property name="basedir" value="${basedir}"/> --> <property name="severity" value="error"/> <property name="fileExtensions" value="java, properties, xml"/> <!-- Excludes all 'module-info.java' files --> <!-- See https://checkstyle.org/config_filefilters.html --> <module name="BeforeExecutionExclusionFileFilter"> <property name="fileNamePattern" value="module\-info\.java$"/> </module> <!-- https://checkstyle.org/config_filters.html#SuppressionFilter --> <module name="SuppressionFilter"> <property name="file" value="${org.checkstyle.sun.suppressionfilter.config}" default="checkstyle-suppressions.xml" /> <property name="optional" value="true"/> </module> <!-- Checks that a package-info.java file exists for each package. --> <!-- See https://checkstyle.org/config_javadoc.html#JavadocPackage --> <module name="JavadocPackage"/> <!-- Checks whether files end with a new line. --> <!-- See https://checkstyle.org/config_misc.html#NewlineAtEndOfFile --> <module name="NewlineAtEndOfFile"/> <!-- Checks that property files contain the same keys. --> <!-- See https://checkstyle.org/config_misc.html#Translation --> <module name="Translation"/> <!-- Checks for Size Violations. --> <!-- See https://checkstyle.org/config_sizes.html --> <module name="FileLength"/> <module name="LineLength"> <property name="fileExtensions" value="java"/> </module> <!-- Checks for whitespace --> <!-- See https://checkstyle.org/config_whitespace.html --> <module name="FileTabCharacter"/> <!-- Miscellaneous other checks. --> <!-- See https://checkstyle.org/config_misc.html --> <module name="RegexpSingleline"> <property name="format" value="\s+$"/> <property name="minimum" value="0"/> <property name="maximum" value="0"/> <property name="message" value="Line has trailing spaces."/> </module> <!-- Checks for Headers --> <!-- See https://checkstyle.org/config_header.html --> <!-- <module name="Header"> --> <!-- <property name="headerFile" value="${checkstyle.header.file}"/> --> <!-- <property name="fileExtensions" value="java"/> --> <!-- </module> --> <module name="TreeWalker"> <!-- Checks for Javadoc comments. --> <!-- See https://checkstyle.org/config_javadoc.html --> <module name="InvalidJavadocPosition"/> <module name="JavadocMethod"/> <module name="JavadocType"/> <module name="JavadocVariable"/> <module name="JavadocStyle"/> <module name="MissingJavadocMethod"/> <!-- Checks for Naming Conventions. --> <!-- See https://checkstyle.org/config_naming.html --> <module name="ConstantName"/> <module name="LocalFinalVariableName"/> <module name="LocalVariableName"/> <module name="MemberName"/> <module name="MethodName"/> <module name="PackageName"/> <module name="ParameterName"/> <module name="StaticVariableName"/> <module name="TypeName"/> <!-- Checks for imports --> <!-- See https://checkstyle.org/config_imports.html --> <module name="AvoidStarImport"/> <module name="IllegalImport"/> <!-- defaults to sun.* packages --> <module name="RedundantImport"/> <module name="UnusedImports"> <property name="processJavadoc" value="false"/> </module> <!-- Checks for Size Violations. --> <!-- See https://checkstyle.org/config_sizes.html --> <module name="MethodLength"/> <module name="ParameterNumber"/> <!-- Checks for whitespace --> <!-- See https://checkstyle.org/config_whitespace.html --> <module name="EmptyForIteratorPad"/> <module name="GenericWhitespace"/> <module name="MethodParamPad"/> <module name="NoWhitespaceAfter"/> <module name="NoWhitespaceBefore"/> <module name="OperatorWrap"/> <module name="ParenPad"/> <module name="TypecastParenPad"/> <module name="WhitespaceAfter"/> <module name="WhitespaceAround"/> <!-- Modifier Checks --> <!-- See https://checkstyle.org/config_modifier.html --> <module name="ModifierOrder"/> <module name="RedundantModifier"/> <!-- Checks for blocks. You know, those {}'s --> <!-- See https://checkstyle.org/config_blocks.html --> <module name="AvoidNestedBlocks"/> <module name="EmptyBlock"/> <module name="LeftCurly"/> <module name="NeedBraces"/> <module name="RightCurly"/> <!-- Checks for common coding problems --> <!-- See https://checkstyle.org/config_coding.html --> <module name="EmptyStatement"/> <module name="EqualsHashCode"/> <module name="HiddenField"/> <module name="IllegalInstantiation"/> <module name="InnerAssignment"/> <module name="MagicNumber"/> <module name="MissingSwitchDefault"/> <module name="MultipleVariableDeclarations"/> <module name="SimplifyBooleanExpression"/> <module name="SimplifyBooleanReturn"/> <!-- Checks for class design --> <!-- See https://checkstyle.org/config_design.html --> <module name="DesignForExtension"/> <module name="FinalClass"/> <module name="HideUtilityClassConstructor"/> <module name="InterfaceIsType"/> <module name="VisibilityModifier"/> <!-- Miscellaneous other checks. --> <!-- See https://checkstyle.org/config_misc.html --> <module name="ArrayTypeStyle"/> <module name="FinalParameters"/> <module name="TodoComment"/> <module name="UpperEll"/> <!-- https://checkstyle.org/config_filters.html#SuppressionXpathFilter --> <module name="SuppressionXpathFilter"> <property name="file" value="${org.checkstyle.sun.suppressionxpathfilter.config}" default="checkstyle-xpath-suppressions.xml" /> <property name="optional" value="true"/> </module> </module> </module>
-
Findbugs配置
在这里我也只配置了过滤EI2、EI这两种bug的配置,这些bug在这里都有描述Bug descriptions — spotbugs 4.7.3 documentation
projectRoot/config/findbugs/exclude.xml
<?xml version="1.0" encoding="UTF-8"?> <FindBugsFilter xmlns="https://github.com/spotbugs/filter/3.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://github.com/spotbugs/filter/3.0.0 https://raw.githubusercontent.com/spotbugs/spotbugs/3.1.0/spotbugs/etc/findbugsfilter.xsd"> <Match> <!--设置需要匹配的包--> <Package name="~com.hhoa.project.*"/> <!--设置需要排除的Bug类型--> <Bug code="EI2, EI"/> </Match> </FindBugsFilter>
- 运行
配置好了当然得跑起来啦,让我们来看看效果!
使用Gradle进行构建将会自动进行check
、spotbugsMain
和spotbugsTest
这三个任务,也可以通过verification
选项
任务完成后,就会生成一系列报告。
我们通过打开html或者xml文件查看报告
通过查看报告我们可以去修改没有发现的Bug或者不规范的地方。
配合CICD我们可以快速交付高质量代码!
参考
-
https://checkstyle.org/