Maven Checkstyle and Eclipse

Have you ever tried to setup your multi-module Maven project with a shared checkstyle configuration and connect it to your eclipse IDE? If you have, I am sure you ‘d agree that it was not as trivial as it should be…

Recently, I had the opportunity to help with the maven-ization of gwt-platform. It used to be a single ant-build project with Checkstyle setup. Also, this setup was working fine in Eclipse without particular manual effort. With the migration to maven the project was split into many sub-modules and a single Checkstyle configuration consisting of: config, header and suppressions files. If this is what you are searching for then stay tuned.

The first step is to share Checkstyle configuration among the sub-modules. You should create a separate host project for the shared Checkstyle configuration. Then you add it as a dependency to maven-checkstyle-plugin e.g.

<plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-checkstyle-plugin</artifactId>
      <version>2.6</version>
      <configuration>
            <configLocation>/checkstyle.xml</configLocation>
            <headerLocation>/header.txt</headerLocation>
            <suppressionsLocation>/suppressions.xml</suppressionsLocation>
      </configuration>
      <dependencies>
            <dependency>
                  <groupId>${project.groupId}</groupId>
                  <artifactId>build-tools</artifactId>
                  <version>${project.version}</version>
            </dependency>
      </dependencies>
</plugin>

This technique is better explained here. Maven-wise your Checkstyle setup is ready. You may run mvn checkstyle:checkstyle to perform a Checkstyle analysis, and generate a report on violations.

The second step is to let Eclipse know about your Checkstyle configuration. This will require to setup maven-eclipse-plugin e.g.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-eclipse-plugin</artifactId>
    <version>2.8</version>
    <configuration>
        <additionalBuildcommands>
            <buildcommand>net.sf.eclipsecs.core.CheckstyleBuilder</buildcommand>
        </additionalBuildcommands>
        <additionalProjectnatures>
            <projectnature>net.sf.eclipsecs.core.CheckstyleNature</projectnature>
        </additionalProjectnatures>
        <additionalConfig>
            <file>
                <name>.checkstyle</name>
                <location>/eclipse-checkstyle.xml</location>
            </file>
        </additionalConfig>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>build-tools</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
</plugin>

Notice the eclipse-checkstyle.xml. This file is located in build-tools as well and contains the information needed by Eclipse to setup Checkstyle. It should look like this:

<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
    <local-check-config name="[CS_CONFIG_NAME]" location="target/checkstyle-checker.xml" type="project" description="">
        <additional-data name="protect-config-file" value="false"/>
    </local-check-config>
    <fileset name="all" enabled="true" check-config-name="[CS_CONFIG_NAME]" local="true">
        <file-match-pattern match-pattern="^src[/\\]." include-pattern="true"/>
    </fileset>
</fileset-config>

In the above snippet, you might noticed that Eclipse will look for the target/checkstyle-checker.xml file which is created by maven-checkstyle-plugin when checkstyle goal runs. For that reason, checkstyle goal should run before the execution of eclipse:eclipse. Also, you should take into account that maven-eclipse-plugin will invoke the execution of the lifecycle phase generate-resources before executing itself.
Apparently, a suitable lifecycle phase to run checkstyle is the validate phase e.g.

<plugin>
    ...
    <artifactId>maven-checkstyle-plugin</artifactId>
    ...
    <executions>
        <execution>
            <id>validate</id>
            <phase>validate</phase>
            <goals>
                <goal>checkstyle</goal>
            </goals>
        </execution>
    </executions>
</plugin>

We are almost there… Now you should make sure your checkstyle configuration is found properly inside eclipse (in particular your header and suppression files). Unfortunately, eclipse will not resolve relative paths inside your Checkstyle configuration file resulting in errors e.g.

You need to wire the header and the suppressions file into your Checkstyle configuration in an Eclipse friendly manner i.e. use full paths 🙂

After struggling for a while with various tweaks (like this one) I found a relative clean workaround which works with both, Eclipse and Maven.

<plugin>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <configuration>
        <propertiesLocation>/checkstyle.properties</propertiesLocation>
        <propertyExpansion>basedir=${project.basedir}</propertyExpansion>
        ...
    </configuration>
    ...
</plugin>

the checkstyle.properties file resides in build-tools module and should look like:

header.file=target/checkstyle-header.txt
suppressions.file=target/checkstyle-suppressions.xml

and finally, inside your Checkstyle configuration:

...
<module name="Header">
    <property name="fileExtensions" value="java"/>
    <property name="severity" value="error"/>
    <property name="headerFile" value="${basedir}/${header.file}"/>
</module>
<module name="SuppressionFilter">
    <property name="file" value="${basedir}/${suppressions.file}"/>
</module>
...

Finally! Now, you should be able to get your checkstyle reports from both Eclipse and Maven.

For a complete/complex working example you might check the sources of gwt-platform.

PS1. I found a similar approach in Apache CXF, which I found it in some extend complicated since it is using a combination of ant, xslt, and the ‘copy’ task to create all of the desired settings files.

PS2. This is my first ever blog. Hooray!

Advertisements
This entry was posted in Java and tagged , , . Bookmark the permalink.

3 Responses to Maven Checkstyle and Eclipse

  1. Great writeup! Thank you! Now, I wonder how we can get the same functionality when using the m2e plugin instead of mvn eclipse:eclipse…

  2. Jos Groen says:

    will this be a typo ?

    <groupId>${project.artifactId}<groupId>
    <artifactId>build-tools<artifactId>
    <version>${project.version}<version>

    groupId schould be ${project.groupId}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s