java-quality

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Java Quality - Quick Reference

Java 质量 - 快速参考

When NOT to Use This Skill

什么时候不要使用该技能

  • SonarQube generic setup - Use
    sonarqube
    skill
  • Spring Boot testing - Use Spring Boot test skills
  • Security scanning - Use
    java-security
    skill
  • Coverage reporting - Use
    jacoco
    skill
Deep Knowledge: Use
mcp__documentation__fetch_docs
with technology:
spring-boot
for framework-specific patterns.
  • 通用 SonarQube 配置 - 使用
    sonarqube
    技能
  • Spring Boot 测试 - 使用 Spring Boot 测试相关技能
  • 安全扫描 - 使用
    java-security
    技能
  • 覆盖率报告 - 使用
    jacoco
    技能
深度知识: 如需框架专属模式,可调用
mcp__documentation__fetch_docs
并指定技术为
spring-boot

Tool Overview

工具概览

ToolFocusSpeedIntegration
CheckstyleCode style, formattingFastMaven/Gradle
SpotBugsBug patterns, bytecodeMediumMaven/Gradle
PMDCode smells, complexityFastMaven/Gradle
SonarJavaAll-in-oneSlowSonarQube
Error ProneCompile-time bugsFastCompiler plugin
工具侧重方向速度集成方式
Checkstyle代码风格、格式化Maven/Gradle
SpotBugsBug 模式、字节码检查中等Maven/Gradle
PMD代码异味、复杂度Maven/Gradle
SonarJava全能型检查SonarQube
Error Prone编译期 Bug 检查编译器插件

Checkstyle Setup

Checkstyle 配置

Maven Configuration

Maven 配置

xml
<!-- pom.xml -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>3.3.1</version>
    <configuration>
        <configLocation>checkstyle.xml</configLocation>
        <consoleOutput>true</consoleOutput>
        <failsOnError>true</failsOnError>
        <violationSeverity>warning</violationSeverity>
    </configuration>
    <executions>
        <execution>
            <id>validate</id>
            <phase>validate</phase>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>com.puppycrawl.tools</groupId>
            <artifactId>checkstyle</artifactId>
            <version>10.12.5</version>
        </dependency>
    </dependencies>
</plugin>
xml
<!-- pom.xml -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>3.3.1</version>
    <configuration>
        <configLocation>checkstyle.xml</configLocation>
        <consoleOutput>true</consoleOutput>
        <failsOnError>true</failsOnError>
        <violationSeverity>warning</violationSeverity>
    </configuration>
    <executions>
        <execution>
            <id>validate</id>
            <phase>validate</phase>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>com.puppycrawl.tools</groupId>
            <artifactId>checkstyle</artifactId>
            <version>10.12.5</version>
        </dependency>
    </dependencies>
</plugin>

checkstyle.xml (Google Style Based)

checkstyle.xml(基于 Google 代码风格)

xml
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
    "https://checkstyle.org/dtds/configuration_1_3.dtd">

<module name="Checker">
    <property name="severity" value="warning"/>
    <property name="fileExtensions" value="java"/>

    <module name="TreeWalker">
        <!-- Naming -->
        <module name="ConstantName"/>
        <module name="LocalVariableName"/>
        <module name="MemberName"/>
        <module name="MethodName"/>
        <module name="PackageName"/>
        <module name="ParameterName"/>
        <module name="TypeName"/>

        <!-- Imports -->
        <module name="IllegalImport"/>
        <module name="RedundantImport"/>
        <module name="UnusedImports"/>

        <!-- Size -->
        <module name="LineLength">
            <property name="max" value="120"/>
        </module>
        <module name="MethodLength">
            <property name="max" value="50"/>
        </module>
        <module name="ParameterNumber">
            <property name="max" value="5"/>
        </module>

        <!-- Complexity -->
        <module name="CyclomaticComplexity">
            <property name="max" value="10"/>
        </module>
        <module name="NPathComplexity">
            <property name="max" value="200"/>
        </module>

        <!-- Best Practices -->
        <module name="EmptyBlock"/>
        <module name="EqualsHashCode"/>
        <module name="HiddenField"/>
        <module name="MissingSwitchDefault"/>
        <module name="SimplifyBooleanExpression"/>
        <module name="SimplifyBooleanReturn"/>
    </module>

    <!-- File-level checks -->
    <module name="FileLength">
        <property name="max" value="500"/>
    </module>
    <module name="NewlineAtEndOfFile"/>
</module>
xml
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
    "https://checkstyle.org/dtds/configuration_1_3.dtd">

<module name="Checker">
    <property name="severity" value="warning"/>
    <property name="fileExtensions" value="java"/>

    <module name="TreeWalker">
        <!-- 命名规范 -->
        <module name="ConstantName"/>
        <module name="LocalVariableName"/>
        <module name="MemberName"/>
        <module name="MethodName"/>
        <module name="PackageName"/>
        <module name="ParameterName"/>
        <module name="TypeName"/>

        <!-- 导入规范 -->
        <module name="IllegalImport"/>
        <module name="RedundantImport"/>
        <module name="UnusedImports"/>

        <!-- 长度限制 -->
        <module name="LineLength">
            <property name="max" value="120"/>
        </module>
        <module name="MethodLength">
            <property name="max" value="50"/>
        </module>
        <module name="ParameterNumber">
            <property name="max" value="5"/>
        </module>

        <!-- 复杂度控制 -->
        <module name="CyclomaticComplexity">
            <property name="max" value="10"/>
        </module>
        <module name="NPathComplexity">
            <property name="max" value="200"/>
        </module>

        <!-- 最佳实践 -->
        <module name="EmptyBlock"/>
        <module name="EqualsHashCode"/>
        <module name="HiddenField"/>
        <module name="MissingSwitchDefault"/>
        <module name="SimplifyBooleanExpression"/>
        <module name="SimplifyBooleanReturn"/>
    </module>

    <!-- 文件级别检查 -->
    <module name="FileLength">
        <property name="max" value="500"/>
    </module>
    <module name="NewlineAtEndOfFile"/>
</module>

Commands

常用命令

bash
undefined
bash
undefined

Run Checkstyle

运行 Checkstyle 检查

./mvnw checkstyle:check
./mvnw checkstyle:check

Generate report

生成报告

./mvnw checkstyle:checkstyle
undefined
./mvnw checkstyle:checkstyle
undefined

SpotBugs Setup

SpotBugs 配置

Maven Configuration

Maven 配置

xml
<!-- pom.xml -->
<plugin>
    <groupId>com.github.spotbugs</groupId>
    <artifactId>spotbugs-maven-plugin</artifactId>
    <version>4.8.3.0</version>
    <configuration>
        <effort>Max</effort>
        <threshold>Medium</threshold>
        <failOnError>true</failOnError>
        <plugins>
            <plugin>
                <groupId>com.h3xstream.findsecbugs</groupId>
                <artifactId>findsecbugs-plugin</artifactId>
                <version>1.12.0</version>
            </plugin>
        </plugins>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
</plugin>
xml
<!-- pom.xml -->
<plugin>
    <groupId>com.github.spotbugs</groupId>
    <artifactId>spotbugs-maven-plugin</artifactId>
    <version>4.8.3.0</version>
    <configuration>
        <effort>Max</effort>
        <threshold>Medium</threshold>
        <failOnError>true</failOnError>
        <plugins>
            <plugin>
                <groupId>com.h3xstream.findsecbugs</groupId>
                <artifactId>findsecbugs-plugin</artifactId>
                <version>1.12.0</version>
            </plugin>
        </plugins>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Exclude False Positives

排除误报

xml
<!-- spotbugs-exclude.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
    <!-- Exclude generated code -->
    <Match>
        <Package name="~.*\.generated\..*"/>
    </Match>

    <!-- Exclude specific patterns -->
    <Match>
        <Bug pattern="EI_EXPOSE_REP"/>
        <Class name="~.*Dto"/>
    </Match>
</FindBugsFilter>
xml
<!-- spotbugs-exclude.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
    <!-- 排除自动生成的代码 -->
    <Match>
        <Package name="~.*\.generated\..*"/>
    </Match>

    <!-- 排除特定规则 -->
    <Match>
        <Bug pattern="EI_EXPOSE_REP"/>
        <Class name="~.*Dto"/>
    </Match>
</FindBugsFilter>

Commands

常用命令

bash
undefined
bash
undefined

Run SpotBugs

运行 SpotBugs 检查

./mvnw spotbugs:check
./mvnw spotbugs:check

Generate report

生成报告

./mvnw spotbugs:spotbugs
./mvnw spotbugs:spotbugs

GUI viewer

打开 GUI 查看器

./mvnw spotbugs:gui
undefined
./mvnw spotbugs:gui
undefined

Common SpotBugs Warnings

常见 SpotBugs 警告

Bug IDDescriptionFix
NP_NULL_ON_SOME_PATHPossible null dereferenceAdd null check or use Optional
EI_EXPOSE_REPReturns mutable objectReturn defensive copy
MS_SHOULD_BE_FINALStatic field should be finalAdd final modifier
SQL_INJECTIONSQL injection riskUse parameterized queries
DM_DEFAULT_ENCODINGUses default encodingSpecify charset explicitly
Bug ID描述修复方案
NP_NULL_ON_SOME_PATH可能出现空指针引用添加空值校验或使用 Optional
EI_EXPOSE_REP返回了可变对象返回防御性拷贝
MS_SHOULD_BE_FINAL静态字段应该声明为 final添加 final 修饰符
SQL_INJECTION存在 SQL 注入风险使用参数化查询
DM_DEFAULT_ENCODING使用了系统默认编码显式指定字符集

PMD Setup

PMD 配置

Maven Configuration

Maven 配置

xml
<!-- pom.xml -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-pmd-plugin</artifactId>
    <version>3.21.2</version>
    <configuration>
        <rulesets>
            <ruleset>pmd-rules.xml</ruleset>
        </rulesets>
        <failOnViolation>true</failOnViolation>
        <printFailingErrors>true</printFailingErrors>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
</plugin>
xml
<!-- pom.xml -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-pmd-plugin</artifactId>
    <version>3.21.2</version>
    <configuration>
        <rulesets>
            <ruleset>pmd-rules.xml</ruleset>
        </rulesets>
        <failOnViolation>true</failOnViolation>
        <printFailingErrors>true</printFailingErrors>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
</plugin>

pmd-rules.xml

pmd-rules.xml 规则文件

xml
<?xml version="1.0"?>
<ruleset name="Custom Rules">
    <description>Custom PMD ruleset</description>

    <!-- Best Practices -->
    <rule ref="category/java/bestpractices.xml">
        <exclude name="JUnitTestContainsTooManyAsserts"/>
    </rule>

    <!-- Code Style -->
    <rule ref="category/java/codestyle.xml">
        <exclude name="AtLeastOneConstructor"/>
        <exclude name="OnlyOneReturn"/>
    </rule>

    <!-- Design -->
    <rule ref="category/java/design.xml">
        <exclude name="LawOfDemeter"/>
    </rule>

    <!-- Error Prone -->
    <rule ref="category/java/errorprone.xml"/>

    <!-- Performance -->
    <rule ref="category/java/performance.xml"/>

    <!-- Custom thresholds -->
    <rule ref="category/java/design.xml/CyclomaticComplexity">
        <properties>
            <property name="methodReportLevel" value="10"/>
        </properties>
    </rule>

    <rule ref="category/java/design.xml/CognitiveComplexity">
        <properties>
            <property name="reportLevel" value="15"/>
        </properties>
    </rule>
</ruleset>
xml
<?xml version="1.0"?>
<ruleset name="Custom Rules">
    <description>Custom PMD ruleset</description>

    <!-- 最佳实践 -->
    <rule ref="category/java/bestpractices.xml">
        <exclude name="JUnitTestContainsTooManyAsserts"/>
    </rule>

    <!-- 代码风格 -->
    <rule ref="category/java/codestyle.xml">
        <exclude name="AtLeastOneConstructor"/>
        <exclude name="OnlyOneReturn"/>
    </rule>

    <!-- 设计规范 -->
    <rule ref="category/java/design.xml">
        <exclude name="LawOfDemeter"/>
    </rule>

    <!-- 易出错场景检查 -->
    <rule ref="category/java/errorprone.xml"/>

    <!-- 性能优化检查 -->
    <rule ref="category/java/performance.xml"/>

    <!-- 自定义阈值 -->
    <rule ref="category/java/design.xml/CyclomaticComplexity">
        <properties>
            <property name="methodReportLevel" value="10"/>
        </properties>
    </rule>

    <rule ref="category/java/design.xml/CognitiveComplexity">
        <properties>
            <property name="reportLevel" value="15"/>
        </properties>
    </rule>
</ruleset>

Commands

常用命令

bash
undefined
bash
undefined

Run PMD

运行 PMD 检查

./mvnw pmd:check
./mvnw pmd:check

Generate report

生成报告

./mvnw pmd:pmd
./mvnw pmd:pmd

Copy-paste detection

重复代码检测

./mvnw pmd:cpd
undefined
./mvnw pmd:cpd
undefined

Error Prone Setup

Error Prone 配置

Maven Configuration

Maven 配置

xml
<!-- pom.xml -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.12.1</version>
    <configuration>
        <compilerArgs>
            <arg>-XDcompilePolicy=simple</arg>
            <arg>-Xplugin:ErrorProne</arg>
        </compilerArgs>
        <annotationProcessorPaths>
            <path>
                <groupId>com.google.errorprone</groupId>
                <artifactId>error_prone_core</artifactId>
                <version>2.24.1</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>
xml
<!-- pom.xml -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.12.1</version>
    <configuration>
        <compilerArgs>
            <arg>-XDcompilePolicy=simple</arg>
            <arg>-Xplugin:ErrorProne</arg>
        </compilerArgs>
        <annotationProcessorPaths>
            <path>
                <groupId>com.google.errorprone</groupId>
                <artifactId>error_prone_core</artifactId>
                <version>2.24.1</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

Combined Quality Profile

组合质量检测配置

All-in-One Maven Profile

一站式 Maven Profile

xml
<!-- pom.xml -->
<profiles>
    <profile>
        <id>quality</id>
        <build>
            <plugins>
                <!-- Checkstyle -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-checkstyle-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals><goal>check</goal></goals>
                        </execution>
                    </executions>
                </plugin>

                <!-- SpotBugs -->
                <plugin>
                    <groupId>com.github.spotbugs</groupId>
                    <artifactId>spotbugs-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals><goal>check</goal></goals>
                        </execution>
                    </executions>
                </plugin>

                <!-- PMD -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-pmd-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals><goal>check</goal></goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
bash
undefined
xml
<!-- pom.xml -->
<profiles>
    <profile>
        <id>quality</id>
        <build>
            <plugins>
                <!-- Checkstyle -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-checkstyle-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals><goal>check</goal></goals>
                        </execution>
                    </executions>
                </plugin>

                <!-- SpotBugs -->
                <plugin>
                    <groupId>com.github.spotbugs</groupId>
                    <artifactId>spotbugs-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals><goal>check</goal></goals>
                        </execution>
                    </executions>
                </plugin>

                <!-- PMD -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-pmd-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals><goal>check</goal></goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
bash
undefined

Run all quality checks

运行所有质量检查

./mvnw verify -Pquality
undefined
./mvnw verify -Pquality
undefined

Common Code Smells & Fixes

常见代码异味及修复方案

1. God Class

1. 上帝类(God Class)

java
// BAD - Class does too much
public class OrderService {
    public Order createOrder() { ... }
    public void sendEmail() { ... }
    public void generatePdf() { ... }
    public void calculateTax() { ... }
    public void updateInventory() { ... }
}

// GOOD - Single responsibility
public class OrderService {
    private final EmailService emailService;
    private final PdfGenerator pdfGenerator;
    private final TaxCalculator taxCalculator;
    private final InventoryService inventoryService;

    public Order createOrder(OrderRequest request) {
        Order order = buildOrder(request);
        order.setTax(taxCalculator.calculate(order));
        inventoryService.reserve(order.getItems());
        return orderRepository.save(order);
    }
}
java
// 反面示例 - 类承担了过多职责
public class OrderService {
    public Order createOrder() { ... }
    public void sendEmail() { ... }
    public void generatePdf() { ... }
    public void calculateTax() { ... }
    public void updateInventory() { ... }
}

// 正面示例 - 单一职责
public class OrderService {
    private final EmailService emailService;
    private final PdfGenerator pdfGenerator;
    private final TaxCalculator taxCalculator;
    private final InventoryService inventoryService;

    public Order createOrder(OrderRequest request) {
        Order order = buildOrder(request);
        order.setTax(taxCalculator.calculate(order));
        inventoryService.reserve(order.getItems());
        return orderRepository.save(order);
    }
}

2. Long Parameter List

2. 过长参数列表

java
// BAD
public void createUser(String name, String email, String phone,
    String address, String city, String country, String zipCode) { }

// GOOD - Use builder or DTO
public void createUser(CreateUserRequest request) { }

@Builder
public record CreateUserRequest(
    String name,
    String email,
    String phone,
    Address address
) {}
java
// 反面示例
public void createUser(String name, String email, String phone,
    String address, String city, String country, String zipCode) { }

// 正面示例 - 使用构建器或 DTO
public void createUser(CreateUserRequest request) { }

@Builder
public record CreateUserRequest(
    String name,
    String email,
    String phone,
    Address address
) {}

3. Feature Envy

3. 特性依恋(Feature Envy)

java
// BAD - Method uses another object's data excessively
public double calculateTotal(Order order) {
    double total = 0;
    for (OrderItem item : order.getItems()) {
        total += item.getPrice() * item.getQuantity();
        if (item.getDiscount() > 0) {
            total -= item.getPrice() * item.getQuantity() * item.getDiscount();
        }
    }
    return total;
}

// GOOD - Move logic to Order
public class Order {
    public double calculateTotal() {
        return items.stream()
            .mapToDouble(OrderItem::getSubtotal)
            .sum();
    }
}

public class OrderItem {
    public double getSubtotal() {
        double base = price * quantity;
        return discount > 0 ? base * (1 - discount) : base;
    }
}
java
// 反面示例 - 方法过度依赖另一个对象的数据
public double calculateTotal(Order order) {
    double total = 0;
    for (OrderItem item : order.getItems()) {
        total += item.getPrice() * item.getQuantity();
        if (item.getDiscount() > 0) {
            total -= item.getPrice() * item.getQuantity() * item.getDiscount();
        }
    }
    return total;
}

// 正面示例 - 将逻辑移到 Order 类中
public class Order {
    public double calculateTotal() {
        return items.stream()
            .mapToDouble(OrderItem::getSubtotal)
            .sum();
    }
}

public class OrderItem {
    public double getSubtotal() {
        double base = price * quantity;
        return discount > 0 ? base * (1 - discount) : base;
    }
}

4. Primitive Obsession

4. 基本类型偏执

java
// BAD
public void sendEmail(String email) {
    if (!email.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
        throw new IllegalArgumentException("Invalid email");
    }
}

// GOOD - Value object
public record Email(String value) {
    public Email {
        if (!value.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
            throw new IllegalArgumentException("Invalid email: " + value);
        }
    }
}

public void sendEmail(Email email) { ... }
java
// 反面示例
public void sendEmail(String email) {
    if (!email.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
        throw new IllegalArgumentException("Invalid email");
    }
}

// 正面示例 - 使用值对象
public record Email(String value) {
    public Email {
        if (!value.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
            throw new IllegalArgumentException("Invalid email: " + value);
        }
    }
}

public void sendEmail(Email email) { ... }

5. Deep Nesting

5. 深度嵌套

java
// BAD
public void process(Order order) {
    if (order != null) {
        if (order.isValid()) {
            for (OrderItem item : order.getItems()) {
                if (item.isAvailable()) {
                    if (item.getQuantity() > 0) {
                        // process
                    }
                }
            }
        }
    }
}

// GOOD - Guard clauses
public void process(Order order) {
    if (order == null || !order.isValid()) {
        return;
    }

    order.getItems().stream()
        .filter(OrderItem::isAvailable)
        .filter(item -> item.getQuantity() > 0)
        .forEach(this::processItem);
}
java
// 反面示例
public void process(Order order) {
    if (order != null) {
        if (order.isValid()) {
            for (OrderItem item : order.getItems()) {
                if (item.isAvailable()) {
                    if (item.getQuantity() > 0) {
                        // 处理逻辑
                    }
                }
            }
        }
    }
}

// 正面示例 - 使用卫语句
public void process(Order order) {
    if (order == null || !order.isValid()) {
        return;
    }

    order.getItems().stream()
        .filter(OrderItem::isAvailable)
        .filter(item -> item.getQuantity() > 0)
        .forEach(this::processItem);
}

Quality Metrics Targets

质量指标目标

MetricTargetTool
Cyclomatic Complexity< 10Checkstyle, PMD
Cognitive Complexity< 15PMD, SonarQube
Method Length< 50 linesCheckstyle
Class Length< 500 linesCheckstyle
Parameters< 5Checkstyle
Nesting Depth< 4PMD
指标目标值检测工具
圈复杂度< 10Checkstyle, PMD
认知复杂度< 15PMD, SonarQube
方法长度< 50 行Checkstyle
类长度< 500 行Checkstyle
参数数量< 5Checkstyle
嵌套深度< 4PMD

CI/CD Integration

CI/CD 集成

GitHub Actions

GitHub Actions 配置

yaml
name: Quality
on: [push, pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'
          cache: maven

      - name: Run quality checks
        run: ./mvnw verify -Pquality

      - name: Upload reports
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: quality-reports
          path: |
            target/checkstyle-result.xml
            target/spotbugsXml.xml
            target/pmd.xml
yaml
name: Quality
on: [push, pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 配置 JDK
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'
          cache: maven

      - name: 运行质量检查
        run: ./mvnw verify -Pquality

      - name: 上传报告
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: quality-reports
          path: |
            target/checkstyle-result.xml
            target/spotbugsXml.xml
            target/pmd.xml

Anti-Patterns

反模式

Anti-PatternWhy It's BadCorrect Approach
Suppressing all warningsHides real issuesFix or justify individually
No static analysis in CIQuality degrades over timeAdd to build pipeline
Only running CheckstyleMisses bugs and smellsCombine with SpotBugs + PMD
High complexity thresholdsAllows unmaintainable codeKeep < 10 cyclomatic
Excluding entire packagesIgnores quality in areasBe specific with exclusions
反模式危害正确做法
屏蔽所有警告掩盖真实问题逐个修复或单独说明屏蔽理由
CI 中没有配置静态分析代码质量随时间逐步下降加入构建流水线
只运行 Checkstyle遗漏 Bug 和代码异味搭配 SpotBugs + PMD 一起使用
复杂度阈值设置过高允许不可维护的代码存在圈复杂度保持在 10 以内
排除整个包的检测忽略特定区域的质量问题精确指定要排除的内容

Quick Troubleshooting

快速问题排查

IssueLikely CauseSolution
Checkstyle fails on generated codeNo exclusion patternAdd
<exclude>
for generated dirs
SpotBugs false positive on DTOEI_EXPOSE_REP on recordsExclude pattern for DTOs
PMD too slowAnalyzing all filesConfigure incremental analysis
Error Prone conflictsVersion mismatchAlign with JDK version
Quality gate fails in CIDifferent config locallyCommit config files
问题可能原因解决方案
Checkstyle 检测自动生成代码时报错没有配置排除规则为自动生成目录添加
<exclude>
配置
SpotBugs 对 DTO 出现误报记录类触发 EI_EXPOSE_REP 规则为 DTO 添加排除规则
PMD 运行过慢分析了所有文件配置增量分析
Error Prone 出现冲突版本不匹配与 JDK 版本对齐
CI 中质量门禁失败本地和线上配置不一致提交配置文件到代码库

Related Skills

相关技能

  • SonarQube
  • JaCoCo
  • Clean Code
  • Java Security
  • SonarQube
  • JaCoCo
  • Clean Code
  • Java Security