Using Custom Developed Checkstyle Checks

We will guide you through creating a Maven project that produces a jar file of your custom checks. Then we'll include it in one of your projects by adding it as a dependency to the Checkstyle Plugin.

The plugin also provides the ability to define the package names XML document required to reference your custom check modules more easily.

In this example we will be using the example check that can be found on the Checkstyle web site.

Structuring your project

First we set up the directory structure for the custom ckecks project. It looks like this:

mycompany-checkstyle-checks
|-- pom.xml
`-- src
    `-- main
        `-- java
            `-- com
                `-- mycompany
                    `-- checks
                        |-- packagenames.xml
                        `-- MethodLimitCheck.java

Now we'll go through each of the three files one at a time.

pom.xml

Not much to say here, except that we add a dependency on Checkstyle.

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany</groupId>
  <artifactId>mycompany-checkstyle-checks</artifactId>
  <name>MyCompany Checkstyle Checks</name>
  <version>1.0</version>
  <dependencies>
    <dependency>
      <groupId>checkstyle</groupId>
      <artifactId>checkstyle</artifactId>
        <version>2.7</version>
    </dependency>
  </dependencies>
</project>

packagenames.xml

This file lets you specify the names of the packages that you want to be able to use. Here we have added com.mycompany.checks to the standard set of Checkstyle packages. That means that you can use your custom checks in the Checkstyle configuration file, without having to specify their package name.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE checkstyle-packages PUBLIC
  "-//Puppy Crawl//DTD Package Names 1.0//EN"
  "http://www.puppycrawl.com/dtds/packages_1_0.dtd">

<checkstyle-packages>
  <package name="com.mycompany.checks"/>
  <package name="com.puppycrawl.tools.checkstyle">
    <package name="checks">
      <package name="blocks"/>
      <package name="coding"/>
      <package name="design"/>
      <package name="duplicates"/>
      <package name="header"/>
      <package name="imports"/>
      <package name="indentation"/>
      <package name="j2ee"/>
      <package name="javadoc"/>
      <package name="metrics"/>
      <package name="modifier"/>
      <package name="naming"/>
      <package name="sizes"/>
      <package name="whitespace"/>
    </package>
    <package name="filters"/>
  </package>
</checkstyle-packages>

MethodLimitCheck.java

Here is the example check from the Checkstyle site. It checks that your source files don't have more that 30 methods.

package com.mycompany.checks;
import com.puppycrawl.tools.checkstyle.api.*;

public class MethodLimitCheck extends Check
{
    private int max = 30;

    public int[] getDefaultTokens()
    {
        return new int[]{TokenTypes.CLASS_DEF, TokenTypes.INTERFACE_DEF};
    }

    public void visitToken(DetailAST ast)
    {
        // find the OBJBLOCK node below the CLASS_DEF/INTERFACE_DEF
        DetailAST objBlock = ast.findFirstToken(TokenTypes.OBJBLOCK);
        // count the number of direct children of the OBJBLOCK
        // that are METHOD_DEFS
        int methodDefs = objBlock.getChildCount(TokenTypes.METHOD_DEF);
        // report error if limit is reached
        if (methodDefs > max) {
            log(ast.getLineNo(),
                "too many methods, only " + max + " are allowed");
        }
   }
}

Building a JAR for your custom checks project

To be able to use your custom checks in other projects, you need to package and install them. To do that, just run this on the command line:

mvn install

This produces a JAR file with the following contents and installs it into your local repository.

mycompany-checkstyle-checks-1.0.jar

mycompany-checkstyle-checks-1.0.jar
|-- pom.xml
|-- META-INF
|   |-- MANIFEST.MF
|   `-- maven
|       `-- com.mycompany
|           `-- mycompany-checkstyle-checks
|               |-- pom.xml
|               `-- pom.properties
`-- com
    `-- mycompany
        `-- checks
            |-- packagenames.xml
            `-- MethodLimitCheck.class

Using your checks in another project

Now you are ready to make use of your custom checks in another project.

Create a Checkstyle configuration

Create the file checkstyle.xml in the root of the project that wants to use your custom checks. In this file you tell Checkstyle which checks you want to use.

Note: We don't have to specify the fully qualified classname of our check here. That's because we used the packagenames.xml file earlier.

<?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="TreeWalker">
    <module name="MethodLimit"/>
  </module>
</module>

Configure the Checkstyle Plugin to use your custom checks

Finally we need to tell the other project that you want it to use your custom Checkstyle checks. In the pom.xml of that project, add the following configuration.

Note: You have to specify a plugin dependency on mycompany-checkstyle-checks in the <build> element of your pom.xml. It will not work inside the <reporting> element, because <reporting> does not support plugin dependencies. The rest of the configuration is done in the normal way in the <reporting> element.

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
        <version>2.7</version>
        <dependencies>
          <dependency>
            <groupId>com.mycompany</groupId>
            <artifactId>mycompany-checkstyle-checks</artifactId>
            <version>1.0</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
  <reporting>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
        <version>2.7</version>
        <configuration>
          <configLocation>checkstyle.xml</configLocation>
          <packageNamesLocation>com/mycompany/checks/packagenames.xml</packageNamesLocation>
        </configuration>
      </plugin>
    </plugins>
  </reporting>
  ...
</project>