Today I’d like to share my experience about Checkstyle setup for a Java/Maven project of Nuxeo. Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard. By default it supports the Google Java Style Guide and Sun Code Conventions, but is highly configurable. It can be invoked with an ANT task and a command line program.
This task consists several steps:
- Declare Checkstyle plugin in POM
- Customize configuration in
checkstyle.xml
- Skip checks in Maven sub-modules
- Suppress checks in Maven sub-modules
Let’s begin.
Declare Checkstyle Plugin in POM
Checkstyle plugin will be executed for each module of the Maven project, so we
need to declare it in the parent POM, section <plugin>
. And we also need a
customized Checkstyle file, call checkstyle.xml
in project’s root directory.
Naming it checkstyle.xml
is not mandatory, it just seems easier to search.
Personally, I declare the Checkstyle version in <pluginManagement>
section
without extra configuration.
In plugin management:
In plugin:
Customize Configuration in checkstyle.xml
Here’s the Checkstyle configuration file that I used for Nuxeo:
Now let’s take a look into each line.
Root Module: Checker
Checker is the root module, which provides the functionality to check a set of files. Everything being checked here are considered as UTF-8 encoding. In Checker module, it consists two sub-modules, UniqueProperties for unique check in properties files (*.properties), and TreeWalker module for Java files (*.java). Actually, many checks are submodules of the TreeWalker module. The TreeWalker operates by separately transforming each of the Java source files into an abstract syntax tree and then handing the result over to each of its submodules which in turn have a look at certain aspects of the tree.
License Check
The Java file header check is handled by a Regexp module. The header file must be present on top of any Java file as:
where ${start.year}
is a 4-digits match \d{4}
, and ${end.year}
is also a
4-digits match. However, the end year might not exist, when the Java is created
this year. Thus the date combination in regular expression become:
\d{4}(-\d{4})?
. Here’s the complete expression with XML escaping:
Java Modifiers Check
The modifiers are checked by modules ModifierOrder and RedundantModifier. ModifierOrder forces Java code to use the modifier order recommended by Java Language Specification (JLS):
public
protected
private
abstract
default
static
final
transient
volatile
synchronized
native
strictfp
And RedundantModifier will fail the build if any redundant modifiers found.
Other Java Checks
The module OneTopLevelClass detects whether there’s only one top level class
declared as public
or package-private (no modifier). If there’re more than
one, then the build will fail. Indeed, you should use a separated Java file in
this case. The module OneStatementPerLine checks whether there’s only one
statement per line. Other checks are very easy to understand, so I won’t
continue here.
Skip checks in Maven sub-modules
In a multi-modules Maven project, it is important to be able to skip the module. For example, you might want to skip when module contains only static resources, the module is written in another language like JavaScript, or it contains only third-party resources, that you don’t want to modify. In this case, skip the check with one Maven property:
or configure in the Checkstyle plugin:
Suppress Checks in Maven sub-modules
In my case, I don’t want to skip the Checkstyle entirely, but suppress warnings conditionally. So I need to configure Checkstyle plugin to do it:
So the location of suppressions is defined as checkstyle-suppressions.xml
.
Inside this file, we have the expressions for suppression. For example, I want
to suppress all the Regexp check for XXX module, because they don’t use the
same license as other modules:
Another example: