21 Code-Qualität (Checkstyle, PMD, SpotBugs, JaCoCo)

Die Sicherstellung einer hohen Code-Qualität ist in jedem Softwareprojekt von großer Bedeutung. Maven bietet durch Plugins wie Checkstyle, PMD, SpotBugs und JaCoCo komfortable Möglichkeiten, den Code kontinuierlich zu analysieren, Stil- und Architekturregeln durchzusetzen und die Testabdeckung zu überprüfen. Dieses Kapitel stellt die gängigen Tools und deren Einsatz vor.


21.1 1. Checkstyle

21.1.1 1.1 Überblick

Checkstyle überprüft den Java-Quellcode auf Einhaltung festgelegter Code-Conventions und Formatierungsregeln (z.B. Einrückungen, Benennungskonventionen, maximale Zeilenlänge). Es hilft Teams dabei, einen einheitlichen Codestil zu wahren und verhindert unnötige Diskussionen über Formatierungen.

21.1.2 1.2 Typische Konfiguration

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>3.1.2</version>
    <executions>
        <execution>
            <id>checkstyle</id>
            <phase>validate</phase>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <configLocation>checkstyle.xml</configLocation>
        <encoding>UTF-8</encoding>
        <failsOnError>true</failsOnError>
    </configuration>
</plugin>

21.1.3 1.3 Best Practices

  1. Gemeinsame Konfigurationsdatei: Sinnvoll ist ein unternehmensweiter Standard (z.B. checkstyle.xml) im Parent-POM.
  2. Integrierte IDE-Unterstützung: Moderne IDEs können Checkstyle-Regeln schon während der Entwicklung anzeigen.
  3. Regelmäßige Pflege: Code-Regeln sollten an aktuelle Standards (z.B. Java 17+) angepasst werden.

21.2 2. PMD

21.2.1 2.1 Überblick

PMD (Programming Mistakes Detector) erkennt potenzielle Fehler, Code-Smells oder ineffiziente Programmiermuster. Beispielsweise meldet es doppelte Code-Blöcke oder vergessene equals-Methoden.

21.2.2 2.2 Typische Konfiguration

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-pmd-plugin</artifactId>
    <version>3.18.0</version>
    <executions>
        <execution>
            <id>pmd</id>
            <phase>verify</phase>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <printFailingErrors>true</printFailingErrors>
        <failOnViolation>true</failOnViolation>
    </configuration>
</plugin>

21.2.3 2.3 Häufige PMD-Regeln

  1. Unused variables: Warnung, wenn lokale Variablen nie genutzt werden.
  2. Duplicate code: Meldet Code-Duplikate.
  3. Empty catch blocks: Verhindert verschluckte Ausnahmen.

21.2.4 2.4 Best Practices

  1. Bewusste Ausnahmen: Wenn bestimmte Dateien bewusst die Regel brechen, kann man sie über exclusions ausschließen.
  2. Regel-Konfiguration: PMD liefert viele Regeln; nur jene aktivieren, die zum Projekt passen, um false positives zu reduzieren.

21.3 3. SpotBugs (ehem. FindBugs)

21.3.1 3.1 Überblick

SpotBugs spürt Fehlerquellen in Java-Klassen auf. Es findet z.B. mögliche NullPointerExceptions, ineffiziente String-Verarbeitung oder falsch implementierte hashCode/equals-Methoden.

21.3.2 3.2 Typische Konfiguration

<plugin>
    <groupId>com.github.spotbugs</groupId>
    <artifactId>spotbugs-maven-plugin</artifactId>
    <version>4.7.3.0</version>
    <executions>
        <execution>
            <id>spotbugs</id>
            <phase>verify</phase>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <effort>max</effort>
        <threshold>Low</threshold>
        <failOnError>true</failOnError>
    </configuration>
</plugin>

21.3.3 3.3 Häufig gemeldete Bugs

  1. Null pointer dereference: Code-Stellen, wo Objekte möglicherweise null sind.
  2. Unclosed resources: Z.B. Streams oder JDBC-Verbindungen ohne close().
  3. Inefficient use of keySet(): Erkennung ineffizienter Schleifen über Map-Einträge.

21.3.4 3.4 Best Practices

  1. Regelmäßige Pflege: SpotBugs-Regeln an Projektanforderungen anpassen, um Signal-Rausch-Verhältnis zu verbessern.
  2. Ignore-Mechanismus: Wenn manche Warnungen gewollt sind, kann man sie gezielt unterdrücken.
  3. Integration in IDE: Auch hier kann eine IDE-Integration für frühzeitiges Feedback sorgen.

21.4 4. JaCoCo (Java Code Coverage)

21.4.1 4.1 Überblick

JaCoCo misst die Testabdeckung von Java-Klassen. Es unterscheidet unterschiedliche Coverage-Typen (z.B. line coverage, branch coverage). Berichte helfen, Lücken in den Tests aufzudecken und die Testqualität zu verbessern.

21.4.2 4.2 Typische Konfiguration

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.8</version>
    <executions>
        <execution>
            <id>prepare-agent</id>
            <phase>initialize</phase>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>verify</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

21.4.3 4.3 Test Coverage Metriken

  1. Line Coverage: Prozentsatz der ausgeführten Quellcodezeilen.
  2. Branch Coverage: Wie viel Prozent der möglichen Pfade in if-else-Blöcken wurden ausgeführt?
  3. Instruction Coverage: Genauere Metrik auf Bytecode-Level.

21.4.4 4.4 Best Practices

  1. Zielwerte definieren: Sinnvolle Mindestwerte für Coverage festlegen (z.B. 80% line coverage).
  2. Ausschlüsse: Generierte oder trivial boilerplate-Klassen (z.B. DTOs) ggf. aus der Messung ausklammern.
  3. Kombination mit SonarQube: Coverage-Ergebnisse in ein Code-Qualitäts-Dashboard integrieren, um Trends zu beobachten.

21.5 5. Gemeinsame Strategien im Projekt

21.5.1 5.1 Integrationsstufen

21.5.2 5.2 Profile und Konventionen

21.5.3 5.3 Kombination mit SonarQube oder Code Climate


21.6 6. Zusammenfassung

  1. Checkstyle: Garantiert einen konsistenten Codestil.
  2. PMD: Findet Code-Smells, Duplikate und potenzielle Fehlerquellen.
  3. SpotBugs: Analysiert Bytecode, um häufige Fehlerquellen wie NullPointer oder fehlerhafte Implementierungen aufzudecken.
  4. JaCoCo: Misst die Testabdeckung und deckt Lücken in Tests auf.

Durch den konsequenten Einsatz dieser Tools erhalten Entwickler frühzeitiges Feedback zur Code-Qualität. Dies führt zu höherer Wartbarkeit, weniger Produktionsfehlern und einer langfristig stabileren Codebasis. In CI/CD-Pipelines brechen Builds bei Verstößen ab, sodass Probleme nicht bis in den Release-Prozess durchsickern. Mit dieser Kombination aus Analyse- und Coverage-Tools machen Sie einen wichtigen Schritt hin zu einem robusten und qualitätsgesicherten Java-Projekt.