java-quality
Skill2 starsChanged 11 days agoMITView on GitHub
Java code quality with Checkstyle, SpotBugs, PMD, and SonarJava。中文触发:Java 后端 JVM
In this repository131 other files it gives its agents.
- agent-client-network-triageSkill
- architecture-designerSkill
- async-python-patternsSkill
- audit-ci-cost-leversSkill
- awesome-design-mdSkill
- byok-model-retrySkill
- cloudbase-wechat-integrationSkill
- concurrent-edit-attribution-checkSkill
- continuation-state-auditSkill
- counterexample-driven-plan-reviewSkill
- deliver-prdSkill
- desktop-update-push-triageSkill
- diagnose-github-actions-quotaSkill
- diagnose-windows-webview2-blank-windowSkill
- disk-junction-migrationSkill
- distinctive-design-systemsSkill
- dsh-session-format-debugSkill
- electron-app-stuck-spinner-triageSkill
- electron-asar-code-forensicsSkill
- electron-tray-icon-diagnosisSkill
- encrypted-office-visual-inspectionSkill
- frontend-design-ui-uxSkill
- frontend-developmentSkill
- game-designer-toolkitSkill
- game-numeric-designSkill
- github-acceleratorSkill
- global-config-smoke-runnerSkill
- goal-driven-executionSkill
- hid-device-protocol-probeSkill
- i-have-adhdSkill
- injected-context-slimmingSkill
- java-architectSkill
- kafka-best-practicesSkill
- large-sqlite-text-extractionSkill
- local-api-contractsSkill
- local-browser-e2eSkill
- local-db-migrationsSkill
- local-frontend-a11ySkill
- local-performance-evidenceSkill
- local-reverse-proxy-triageSkill
- local-rust-engineeringSkill
- local-spring-mybatisSkill
- mechanize-rule-into-hook-guardSkill
- memory-bank-divergence-repairSkill
- memory-entry-updateSkill
- merge-inbound-qoder-packageSkill
- minigame-dev-proSkill
- miniprogram-developmentSkill
- mongodb-atlas-stream-processingSkill
- mongodb-connectionSkill
- mongodb-mcp-setupSkill
- mongodb-natural-language-queryingSkill
- mongodb-query-optimizerSkill
- mongodb-schema-designSkill
- mongodb-search-and-aiSkill
- mysqlSkill
- nextjs-app-router-patternsSkill
- nginx-config-builderSkill
- nodejs-backend-patternsSkill
- oauth-login-failure-triageSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 9
SonarQube generic setup: - Use sonarqube skill
- Distinctive: line 10
Spring Boot testing: - Use Spring Boot test skills
- Very specific: line 11
Security scanning: - Use java-security skill
- Very specific: line 12
Coverage reporting: - Use jacoco skill
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Java Quality - Quick Reference
When NOT to Use This Skill
- SonarQube generic setup - Use
sonarqubeskill - Spring Boot testing - Use Spring Boot test skills
- Security scanning - Use
java-securityskill - Coverage reporting - Use
jacocoskill
Deep Knowledge: Use
mcp__documentation__fetch_docswith technology:spring-bootfor framework-specific patterns.
Tool Overview
| Tool | Focus | Speed | Integration |
| Checkstyle | Code style, formatting | Fast | Maven/Gradle |
| SpotBugs | Bug patterns, bytecode | Medium | Maven/Gradle |
| PMD | Code smells, complexity | Fast | Maven/Gradle |
| SonarJava | All-in-one | Slow | SonarQube |
| Error Prone | Compile-time bugs | Fast | Compiler plugin |
Checkstyle Setup
Maven Configuration
<!-- 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)
<?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>Commands
# Run Checkstyle
./mvnw checkstyle:check
# Generate report
./mvnw checkstyle:checkstyleSpotBugs Setup
Maven Configuration
<!-- 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
<!-- 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>Commands
# Run SpotBugs
./mvnw spotbugs:check
# Generate report
./mvnw spotbugs:spotbugs
# GUI viewer
./mvnw spotbugs:guiCommon SpotBugs Warnings
| Bug ID | Description | Fix |
| NP_NULL_ON_SOME_PATH | Possible null dereference | Add null check or use Optional |
| EI_EXPOSE_REP | Returns mutable object | Return defensive copy |
| MS_SHOULD_BE_FINAL | Static field should be final | Add final modifier |
| SQL_INJECTION | SQL injection risk | Use parameterized queries |
| DM_DEFAULT_ENCODING | Uses default encoding | Specify charset explicitly |
PMD Setup
Maven Configuration
<!-- 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
<?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>Commands
# Run PMD
./mvnw pmd:check
# Generate report
./mvnw pmd:pmd
# Copy-paste detection
./mvnw pmd:cpdError Prone Setup
Maven Configuration
<!-- 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
<!-- 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># Run all quality checks
./mvnw verify -PqualityCommon Code Smells & Fixes
1. God Class
// 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);
}
}2. Long Parameter List
// 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
) {}3. Feature Envy
// 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;
}
}4. Primitive Obsession
// 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) { ... }5. Deep Nesting
// 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);
}Quality Metrics Targets
| Metric | Target | Tool |
| Cyclomatic Complexity | < 10 | Checkstyle, PMD |
| Cognitive Complexity | < 15 | PMD, SonarQube |
| Method Length | < 50 lines | Checkstyle |
| Class Length | < 500 lines | Checkstyle |
| Parameters | < 5 | Checkstyle |
| Nesting Depth | < 4 | PMD |
CI/CD Integration
GitHub Actions
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.xmlAnti-Patterns
| Anti-Pattern | Why It's Bad | Correct Approach |
| Suppressing all warnings | Hides real issues | Fix or justify individually |
| No static analysis in CI | Quality degrades over time | Add to build pipeline |
| Only running Checkstyle | Misses bugs and smells | Combine with SpotBugs + PMD |
| High complexity thresholds | Allows unmaintainable code | Keep < 10 cyclomatic |
| Excluding entire packages | Ignores quality in areas | Be specific with exclusions |
Quick Troubleshooting
| Issue | Likely Cause | Solution |
| Checkstyle fails on generated code | No exclusion pattern | Add <exclude> for generated dirs |
| SpotBugs false positive on DTO | EI_EXPOSE_REP on records | Exclude pattern for DTOs |
| PMD too slow | Analyzing all files | Configure incremental analysis |
| Error Prone conflicts | Version mismatch | Align with JDK version |
| Quality gate fails in CI | Different config locally | Commit config files |
Related Skills
- SonarQube
- JaCoCo
- Clean Code
- Java Security
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

