Wenn es um Checkstyle geht, scheiden sich die Geister. Beliebt bei jenen, die es konfiguriert haben, gehasst von den Anderen, ist Checkstyle das beliebteste Werkzeug im Java Umfeld, um seinen Code-Style aufzudrängen.

Wie immer man auch zu dem statischen Code-Analyzer steht, für diejenigen, die Checkstyle in mehreren Maven Projekten parallel warten müssen oder möchten, könnte dieser Artikel interessant sein.

Normalerweise ist Checkstyle relativ einfach aufgesetzt. Zunächst wird eine Datei checkstyle.xml erstellt. Die gewählten Regeln werden im Checkstyle Maven-Plugin definiert und referenziert. Bei einem einzelnen Projekt mag dieses Setup völlig ausreichend sein, wenn man nun dieselbe Konfiguration jedoch in mehreren Projekten verwenden möchte, muss diese manuell kopiert und bei Änderungen synchronisiert werden. Gerade in der aktuell sehr beliebten Microservice-Architektur sind, sofern nicht gerade ein monorepo einsetzt wird, oft sehr viele Repositories und Projekte zu verwalten.

Maven to the Rescue

Natürlich hat Maven eine Lösung für uns parat! Diese umfasst folgende Schritte:

  1. Erstellen eines neuen Maven Projektes, welches nur die Checkstyle Konfiguration checkstyle.xml beinhaltet
  2. Diese Projekt als Dependency im Checkstyle Maven-Plugin des ursprünglichen Projektes referenzieren
  3. Abschließend das Maven Checkstyle-Konfigurations Projekt im Maven Repo seiner Wahl veröffentlichen ("publishen")

Fertig!

1. Erstellung eines Projektes für die Checkstyle Konfiguration

Erstelle eine neues Maven Projekt mit der Methode der Wahl. In diesem Beispiel nennen wir die Konfiguration checkstyle.xml und hinterlegen diese in /src/main/resource.

Als Test verwenden wir diese völlig realitätsfremde Restriktion in "line-length" - eine Konfiguration bei der uns sehr schnell auffallen wird, ob unser Unterfangen erfolgreich war ;).

<?xml version="1.0" ?><!DOCTYPE module PUBLIC
        "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
        "<http://www.puppycrawl.com/dtds/configuration_1_2.dtd>">

<module name="Checker">
    <module name="LineLength">
        <property name="max" value="25"/>
    </module>
</module>

Alles was man jetzt noch machen muss, ist das Installieren ins Lokale Repository:

mvn clean install

2. Referenzieren des neue Projektes

Im POM fügt man jetzt beim Checkstyle Maven-Plugin das neue Konfigurations-projekt als Dependency ein:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.puppycrawl.tools</groupId>
            <artifactId>checkstyle</artifactId>
            <version>8.31</version>
        </dependency>
          <dependency>
            <groupId>com.company.projectname</groupId>
            <artifactId>checkstyle-config</artifactId>
            <version>1</version>
        </dependency>
    </dependencies>
    <configuration>
        <configLocation>checkstyle.xml</configLocation>
    </configuration>
</plugin>

Der Dateiname in configLocation muss mit dem des Konfigurationspojektes übereinstimmen. Nicht vergessen das lokale Checkstyle .xml zu löschen. Wenn man jetzt folgendes aufruft:

mvn checkstyle:check

sollte die neue Konfiguration greifen.

3. Make your Config Project Deployable

Manche Maven Repositories, wie zum Beispiel Maven Central, benötigen zwingend ein *-javadoc.jar und *-sources.jar damit man dorthin deployen kann. Da wir hier weder Sourcecode noch JavaDoc haben, müssen wir Platzhalterdateien erstellen. Zum Glück ist das mit Maven recht einfach:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <executions>
        <execution>
            <id>attach-sources</id>
            <goals>
                 <goal>jar-no-fork</goal>
            </goals>
        </execution>
    </executions>
</plugin>

und für JavaDoc

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <executions>
        <execution>
            <id>empty-javadoc-jar</id>
            <phase>package</phase>
            <goals>
                <goal>jar</goal>
            </goals>
            <configuration>
                <classifier>javadoc</classifier>
                <classesDirectory>${basedir}/javadoc</classesDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

Nachdem wir die korrekten Koordinaten für das Distribution Management gesetzt haben, sollten wir nun ohne weitere Probleme das Projekt veröffentlichen können mit

mvn deploy

Ein umfassendes Beispiel, welches auch in Maven Central vertreten ist, findet sich hier.

Wie man "Suppression Filter" verwendet

In der Realität wird bei jedem Projekt der Moment kommen, bei dem eine spezielle Regel an einer Stelle im Code einfach nicht passt. Dazu gibt es in Checkstyle die Möglichkeit Supression Filter in eine Datei auszulagern (uA.). Es macht meist aber keinen Sinn diese Supression Konfiguration global zu teilen, deswegen hat diese auch nichts in unseren Checkstyle Maven Projekt verloren.

Beispiel einer Checkstyle Supression Konfiguration

Es ist aber natürlich weiterhin möglich, dies lokal zu definieren. Wie üblich die Datei erstellen, hier nennen wir sie  checkstyle-suppressions.xml, und im Checkstyle Maven-Plugin referenzieren:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    ...
    <configuration>
        <configLocation>checkstyle.xml</configLocation>
        <suppressionsLocation>checkstyle-suppressions.xml</suppressionsLocation>
    </configuration>
</plugin>

Ein Beispiel eines Projektes, bei dem auch Suppressions verwendet werden mit einer globalen Checkstyle Konfiguration, findet sich hier. (die Checkstyle Maven-Plugin Konfiguration befindet sich im Parent-POM)

Verwendung mit einem IDE Checkstyle Plugin

Wenn man zum Beispiel das exzellente Checkstyle IntelliJ plugin oder ein ähnliches Tooling verwendet, will das natürlich wissen wo die lokale Konfiguration zu finden ist. Dazu muss man zuerst mvn install ausführen, dann findet man die Datei in /target/checkstyle-checker.xml.

Zusammenfassung

Wir haben ein neues Maven Projekt angelegt, welches nur unsere Checkstyle Konfiguration enthält, damit wir es leichter in verschiedenen, anderen Services verwenden können. Wir haben uns dann noch angeschaut, was zu tun wäre, wenn man es in restriktivere Maven Repos veröffentlichen will. Zum Abschluss haben wir noch Suppressions und Support für IDE Plugins behandelt.

Referenzen