A Checkstyle configuration specifies which modules to plug in and apply to Java source files. Modules are structured in a tree whose root is the Checker module. The next level of modules contains:
Many checks are submodules of the TreeWalker FileSetCheck 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.
Checkstyle obtains a configuration from an XML document whose elements specify the configuration's hierarchy of modules and their properties. You provide a file that contains the configuration document when you invoke Checkstyle at the command line, and when you run a Checkstyle task in ant. The documentation directory of the Checkstyle distribution contains a sample configuration file sun_checks.xml which configures Checkstyle to check for the Sun coding conventions.
A module
element in the configuration
XML document specifies a module identified by the element's
name
attribute.
Here is a fragment of a typical configuration document:
<module name="Checker"> <module name="JavadocPackage"/> <module name="TreeWalker"> <module name="AvoidStarImport"/> <module name="ConstantName"/> <module name="EmptyBlock"/> </module> </module>
In this configuration:
Checker
has child
FileSetChecks JavadocPackage
and TreeWalker
. (Module JavadocPackage
checks that all packages
have package documentation.)
TreeWalker
has submodules
AvoidStarImport
, ConstantName
, and EmptyBlock
. (Modules AvoidStarImport
, ConstantName
, and EmptyBlock
check that a Java source
file has no star imports, has valid constant names, and has no
empty blocks, respectively.)
For each configuration module, Checkstyle loads a class
identified by the name
attribute of
the module
. There are several rules
for loading a module's class:
name
, such as loading class com.puppycrawl.tools.checkstyle.TreeWalker
for element:
<module name="com.puppycrawl.tools.checkstyle.TreeWalker">
com.puppycrawl.tools.checkstyle.checks.AvoidStarImport
for element
<module name="AvoidStarImport"/>
com.puppycrawl.tools.checkstyle
,
com.puppycrawl.tools.checkstyle.filters
, and com.puppycrawl.tools.checkstyle.checks
and its sub-packages (only those included in the Checkstyle
distribution). You can specify other packages in a package names XML document
when you invoke Checkstyle at the command line, and when you run a Checkstyle task in ant.
name
concatenated with "Check"
,
such as loading class com.puppycrawl.tools.checkstyle.checks.ConstantNameCheck
for element
<module name="ConstantName"/>
Properties of a module control how the module performs its task.
Each module property has a default value, and you are not
required to define a property in the configuration document if
the default value is satisfactory. To assign a non-default
value to a module's property, define a child property
element of the module
element in the configuration XML
document. Also provide appropriate name
and value
attributes for the property
element.
For example, property max
of module
MethodLength
specifies the maximum
allowable number of lines in a method or constructor, and has
default value 150
. Here is a
configuration of module MethodLength
so that the check reports methods and constructors with more
than 60
lines:
<module name="MethodLength"> <property name="max" value="60"/> </module>
Command line properties and ant Checkstyle task properties apply to the
root Checker
module. Also, properties
are inherited in the module hierarchy. These features make it
easy to define one property value that applies to many
modules. For example, the following configuration fragment
specifies that a tabWidth
of 4
applies to TreeWalker
and its submodules:
<module name="Checker"> <module name="JavadocPackage"/> <module name="TreeWalker"> <property name="tabWidth" value="4"/> <module name="AvoidStarImport"/> <module name="ConstantName"/> ... </module> </module>
The value of a module property can be specified through
property expansion with the ${property_name}
notation, where
property_name
is a command line property or an ant Checkstyle task property. For example,
the following configuration document element gives property
headerFile
the value of command line
property checkstyle.header.file
:
<property name="headerFile" value="${checkstyle.header.file}"/>
You can use property expansion to re-specify a module property value without changing the configuration document.
The property element provides an optional default
attribute which is used when a
property in the value cannot be resolved. For example this
configuration snippet from a central configuration file checks
that methods have javadoc, but allows individual projects to
override the severity by specifying their desired value in the
command line property checkstyle.javadoc.severity
:
<module name="JavaDocMethod"> <property name="severity" value="${checkstyle.javadoc.severity}" default="error"/> </module>
This feature is a great help when setting up a centralized configuration file (e.g. one file for the whole company) to lower configuration maintenance costs. Projects that are happy with the default can simply use that configuration file as is, but individual projects with special needs have the flexibility to adjust a few settings to fit their needs without having to copy and maintain the whole configuration.
All configurations have root module Checker
. Checker
contains:
Checker
also defines properties that are
inherited by all other modules of a configuration.
name | description | type | default value |
---|---|---|---|
basedir | base directory name; stripped off in messages about files | string | null |
localeCountry | locale country for messages | string: either the empty string or an uppercase ISO 3166 2-letter code | default locale country for the Java Virtual Machine |
localeLanguage | locale language for messages | string: either the empty string or a lowercase ISO 639 code | default locale language for the Java Virtual Machine |
charset | name of the file charset | String | System property "file.encoding" |
For example, the following configuration fragment specifies base
directory src/checkstyle
and German
locale for all modules:
<module name="Checker"> <property name="basedir" value="src/checkstyle"/> <property name="localeCountry" value="DE"/> <property name="localeLanguage" value="de"/> <module name="JavadocPackage"/> <module name="TreeWalker"> ... </module> </module>
To configure a Checker
so that it
handles files with the UTF-8
charset:
<module name="Checker"> <property name="charset" value="UTF-8"/> ... </module>
FileSetCheck TreeWalker
checks
individual Java source files and defines properties that are
applicable to checking such files.
name | description | type | default value |
---|---|---|---|
cacheFile | caches information about files that have checked ok; used to avoid repeated checks of the same files | string | null (no cache file) |
tabWidth | number of expanded spaces for a tab character ('\t' ); used in messages and Checks that
require a tab width, such as LineLength |
integer | 8 |
fileExtensions | file type extension to identify java files. Setting this
property is typically only required if your java source code
is preprocessed before compilation and the original files do
not have the extension .java |
String Set | java |
For example, the following configuration fragment specifies
TreeWalker
cache file target/cachefile
, and a tabWidth
of 4
:
<module name="Checker"> <module name="TreeWalker"> <property name="cacheFile" value="target/cachefile"/> <property name="tabWidth" value="4"/> ... </module> </module>
To integrate Checkstyle with BEA Weblogic Workshop 8.1:
<module name="Checker"> <module name="TreeWalker"> <property name="fileExtensions" value="java,ejb,jpf"/> ...
The TreeWalker
module creates a syntax
tree for a Java source file and invokes its submodules, called
Checks, during a walk, or traversal, of the nodes of
the tree. Every node of the syntax tree has a token. A visit to
a node during the traversal triggers all Checks that are
configured for its token. For example, if Check MethodLength
has been configured as a
submodule of TreeWalker
, then a visit
to a node with a method or a constructor definition token
triggers MethodLength
to check the
number of lines of the node's code block.
Some Checks, such as FileLength
and
LineLength
, apply directly to the
source file and do not involve tokens of the syntax tree. Other
Checks are associated with configurable sets of tokens that
trigger the Checks. For example, this element configures Check
MethodLength
:
<module name="MethodLength"/>
The default token set for MethodLength
is {METHOD_DEF, CTOR_DEF}
, method
definition and constructor definition tokens, so TreeWalker
invokes MethodLength
whenever it visits a node with
a METHOD_DEF
or a CTOR_DEF
token.
You specify the trigger tokens for a Check with property tokens
. The value of tokens
is a list that denotes a subset of
the Check's tokens, as in the following element that configures
Check MethodLength
to check the number
of lines of methods only:
<module name="MethodLength"> <property name="tokens" value="METHOD_DEF"/> </module>
To apply particular properties to different subsets of tokens
for a Check, repeat the Check. For example, to check that the
length of each method is at most 150 lines (the default value of
MethodLength
property max
) and the length of each constructor is
at most 60 lines, include the following in the TreeWalker
configuration:
<module name="MethodLength"> <property name="tokens" value="METHOD_DEF"/> </module> <module name="MethodLength"> <property name="tokens" value="CTOR_DEF"/> <property name="max" value="60"/> </module>
Configurations of the Checks are specified in the pages under here.
Each check has a severity property that a
Checkstyle audit assigns to all violations of the check. The
default severity level of a check is error
.
You can use the severity property to control the output of the
plain formatter for the command line
tool and the ANT task. The plain
formatter does not report violations with severity level ignore
, and notes violations with
severity level warning
. For
example, according to the following configuration fragment, the
plain formatter outputs warnings for translation violations:
<module name="Translation"> <property name="severity" value="warning"/> </module>
The XML formatter reports the severity level of every violation
as an attribute of the violation's error
element.
As of Checkstyle 5 all checks can be configured to report custom, configuration specific messages instead of the Checkstyle default messages. This can be useful in cases where the check message should reference corresponding sections in a coding style document or the default is too generic for developers to understand.
An example usage is:
<module name="MemberName"> <property name="format" value="^m[a-zA-Z0-9]*$"/> <message key="name.invalidPattern" value="Member ''{0}'' must start with a lowercase ''m'' (checked pattern ''{1}'')." /> </module>
Each check configuration element can zero or more message
elements. Every check uses one or
more distinct message keys to log violations. If you want to
customize a certain message you need to specify the message key
in the key
attribute of the message
element.
The value
attribute specifies the
custom message pattern, as shown in the example above.
Placeholders used in the default message can also be used in the
custom message. Note that the message pattern must be a valid
java.text.MessageFormat
style pattern,
so be careful about curly braces outside a placeholder
definition.
The obvious question is how do you know which message keys a
Check uses, so that you can override them? Well, that is the
tricky part. To find out which keys a Check uses you currently
need to look into the Check's source code, in conjunction with
the Check's messages.properties
file.
Tools/plugins might come to the rescue on this topic, so have a
look there.
A Checker module has a set of Filter submodules to filter audit events, including the error messages fired by Checks. A Filter can accept or reject an audit event. If all Filters accept an audit event, then the Checker reports the event. If any Filter rejects an event, then the Checker does not report the event.
Filter SeverityMatchFilter
decides
audit events according to the severity
level of the event.
name | description | type | default value |
---|---|---|---|
severity | the severity level of this filter | severity | error |
acceptOnMatch |
If acceptOnMatch is true , then
the filter accepts an audit event if and only if there is
a match between the event's severity level and property
severity. If acceptOnMatch
is false , then the filter
accepts an audit event if and only if there is not a match
between the event's severity level and property severity.
|
boolean | true |
For example, the following configuration fragment directs the
Checker to not report audit events with severity
level info
:
<module name="SeverityMatchFilter"> <property name="severity" value="info"/> <property name="acceptOnMatch" value="false"/> </module>
Filter SuppressionFilter
rejects
audit events for Check errors according to
a suppressions XML
document in a file. If there is no configured
suppressions file, the Filter accepts all audit events.
name | description | type | default value |
---|---|---|---|
file | the name of the suppressions XML document file | string | none |
For example, the following configuration fragment directs the
Checker to use a SuppressionFilter
with suppressions
file docs/suppressions.xml
:
<module name="SuppressionFilter"> <property name="file" value="docs/suppressions.xml"/> </module>
A suppressions XML
document contains a set
of suppress
elements, where
each suppress
element can have the
following attributes:
files
-
a regular expression
matched against the file name associated with an audit
event. It is mandatory.
checks
-
a regular expression
matched against the name of the check associated with an audit
event. Optional if id
is specified.
id
-
a string
matched against the id of the check associated with an audit
event. Optional if checks
is specified.
lines
- a comma-separated list of
values, where each value is
an integer or a
range of integers denoted by integer-integer. It is optional.
columns
- a comma-separated list of
values, where each value is
an integer or a
range of integers denoted by integer-integer. It is optional.
Each audit event is checked against
each suppress
element. It is
suppressed if all specified attributes match against the audit
event.
For example, the following suppressions XML document directs
a SuppressionFilter
to
reject JavadocStyleCheck
errors for
lines 82 and 108 to 122 of
file AbstractComplexityCheck.java
,
and MagicNumberCheck
errors for line
221 of file JavadocStyleCheck.java
:
<?xml version="1.0"?> <!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN" "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> <suppressions> <suppress checks="JavadocStyleCheck" files="AbstractComplexityCheck.java" lines="82,108-122"/> <suppress checks="MagicNumberCheck" files="JavadocStyleCheck.java" lines="221"/> </suppressions>
As another example, imagine that a configuration contains the following:
<module name="DescendantToken"> <property name="id" value="stringEqual"/> <property name="tokens" value="EQUAL,NOT_EQUAL"/> <property name="limitedTokens" value="STRING_LITERAL"/> <property name="maximumNumber" value="0"/> <property name="maximumDepth" value="1"/> </module> <module name="DescendantToken"> <property name="id" value="switchNoDefault"/> <property name="tokens" value="LITERAL_SWITCH"/> <property name="maximumDepth" value="2"/> <property name="limitedTokens" value="LITERAL_DEFAULT"/> <property name="minimumNumber" value="1"/> </module>
Then the following can be used to suppress only the first
check and not the second by using
the id
attribute:
<suppress id="stringEqual" files="SomeTestCode.java"/>
Filter SuppressionCommentFilter
uses
pairs of comments to suppress audit events.
Rationale: Sometimes there are legitimate reasons for violating a check. When this is a matter of the code in question and not personal preference, the best place to override the policy is in the code itself. Semi-structured comments can be associated with the check. This is sometimes superior to a separate suppressions file, which must be kept up-to-date as the source file is edited.
Usage: This filter only works in conjunction with a FileContentsHolder
, since that check makes
the suppression comments in the .java files available sub
rosa. A configuration that includes this filter must
configure FileContentsHolder
as a
child module of TreeWalker
.
name | description | type | default value |
---|---|---|---|
offCommentFormat | comment pattern to trigger filter to begin suppression | regular expression | CHECKSTYLE\:OFF |
onCommentFormat | comment pattern to trigger filter to end suppression | regular expression | CHECKSTYLE\:ON |
checkFormat | check pattern to suppress | regular expression | .* (all checks) |
messageFormat | message pattern to suppress | regular expression | none |
checkCPP | whether to check C++ style comments (// ) |
boolean | true |
checkC | whether to check C style comments (/* ... */ ) |
boolean | true |
offCommentFormat and onCommentFormat must have equal paren counts.
To configure the check that makes comments available to the filter:
<module name="TreeWalker"> ... <module name="FileContentsHolder"/> ... </module>
To configure a filter to suppress audit events between a comment
containing CHECKSTYLE:OFF
and a comment containing
CHECKSTYLE:ON
:
<module name="SuppressionCommentFilter"/>
To configure a filter to suppress audit events between a comment
containing line BEGIN GENERATED CODE
and a comment
containing line END GENERATED CODE
:
<module name="SuppressionCommentFilter"> <property name="offCommentFormat" value="BEGIN GENERATED CODE"/> <property name="onCommentFormat" value="END GENERATED CODE"/> </module>
To configure a filter so that // stop constant
check
and // resume constant check
marks
legitimate constant names:
<module name="SuppressionCommentFilter"> <property name="offCommentFormat" value="stop constant check"/> <property name="onCommentFormat" value="resume constant check"/> <property name="checkFormat" value="ConstantNameCheck"/> </module>
To configure a filter so that UNUSED OFF:
var
and UNUSED ON: var
marks a
variable or parameter known not to be used by the code by
matching the variable name in the message:
<module name="SuppressionCommentFilter"> <property name="offCommentFormat" value="UNUSED OFF\: (\w+)"/> <property name="onCommentFormat" value="UNUSED ON\: (\w+)"/> <property name="checkFormat" value="Unused"/> <property name="messageFormat" value="^Unused \w+ '$1'.$"/> </module>
To configure a filter so that CSOFF: regexp
and CSN: regexp
mark a matching check:
<module name="SuppressionCommentFilter"> <property name="offCommentFormat" value="CSOFF\: ([\w\|]+)"/> <property name="onCommentFormat" value="CSON\: ([\w\|]+)"/> <property name="checkFormat" value="$1"/> </module>
To configure a filter to suppress all audit events between a comment
containing CHECKSTYLE_OFF: ALL
and a comment containing
CHECKSTYLE_OFF: ALL
except for the EqualsHashCode check:
<module name="SuppressionCommentFilter"> <property name="offCommentFormat" value="CHECKSTYLE_OFF: ALL"/> <property name="onCommentFormat" value="CHECKSTYLE_ON: ALL"/> <property name="checkFormat" value="^((?!(EqualsHashCode)).)*$"/> </module>
Filter SuppressWithNearbyCommentFilter
uses
individual comments to suppress audit events.
Rationale: Same as SuppressionCommentFilter
.
Whereas the SuppressionCommentFilter uses matched pairs of
filters to turn on/off comment matching,
SuppressWithNearbyCommentFilter
uses
single comments. This requires fewer lines to mark a region, and
may be aesthetically preferable in some contexts.
Usage: This filter only works in conjunction with a FileContentsHolder
, since that check makes
the suppression comments in the .java files available sub
rosa. A configuration that includes this filter must
configure FileContentsHolder
as a
child module of TreeWalker
.
name | description | type | default value |
---|---|---|---|
commentFormat | comment pattern to trigger filter to begin suppression | regular expression | SUPPRESS CHECKSTYLE (\w+) |
checkFormat | check pattern to suppress | regular expression | $1 |
messageFormat | message pattern to suppress | regular expression | none |
influenceFormat | a negative/zero/positive value that defines the number of lines preceding/at/following the suppression comment | regular expression | 0 (the line containing the comment) |
checkCPP | whether to check C++ style comments (// ) |
boolean | true |
checkC | whether to check C style comments (/* ... */ ) |
boolean | true |
To configure the check that makes comments available to the filter:
<module name="TreeWalker"> ... <module name="FileContentsHolder"/> ... </module>
To configure a filter to suppress audit events for check
on any line with a comment SUPPRESS CHECKSTYLE check
:
<module name="SuppressWithNearbyCommentFilter"/>
To configure a filter to suppress all audit events on any line
containing the comment CHECKSTYLE IGNORE THIS LINE
:
<module name="SuppressWithNearbyCommentFilter"> <property name="commentFormat" value="CHECKSTYLE IGNORE THIS LINE"/> <property name="checkFormat" value=".*"/> <property name="influenceFormat" value="0"/> </module>
To configure a filter so that
// Ok to catch (Throwable|Exception|RuntimeException) here
permits the current and previous line to avoid generating an IllegalCatch
audit event:
<module name="SuppressWithNearbyCommentFilter"> <property name="commentFormat" value="Ok to catch (\w+) here"/> <property name="checkFormat" value="IllegalCatchCheck"/> <property name="messageFormat" value="$1"/> <property name="influenceFormat" value="-1"/> </module>
To configure a filter so that CHECKSTYLE IGNORE check FOR NEXT var LINES
avoids triggering any audits for the given check for the current line and the next var lines
(for a total of var+1 lines):
<module name="SuppressWithNearbyCommentFilter"> <property name="commentFormat" value="CHECKSTYLE IGNORE (\w+) FOR NEXT (\d+) LINES"/> <property name="checkFormat" value="$1"/> <property name="messageFormat" value="$2"/> </module>
In addition to an audit reporter for text or XML output, a
Checker can have custom
AuditListeners that handle audit events. In order to use a
custom listener, add a Checker
submodule for the
listener and its properties. For example, to configure a Checker
so that it uses custom listener VerboseListener to
print audit messages to a file named "audit.txt",
include the following module in the configuration file:
<module name="com.mycompany.listeners.VerboseListener"> <property name="file" value="audit.txt"/> </module>
Checkstyle loads a module class according to the name
of a module
element, and automatically appends pre-specified package
prefixes to that name
in its search
for a loadable class. By default, Checkstyle applies packages
com.puppycrawl.tools.checkstyle
,
com.puppycrawl.tools.checkstyle.filters
, and com.puppycrawl.tools.checkstyle.checks
as
well as any sub-packages of com.puppycrawl.tools.checkstyle.checks
that
are distributed with Checkstyle.
To specify other packages to apply,
create a package names XML document in a file
named checkstyle_packages.xml
,
and provide that file in the root of the .jar containing your
custom checks.
Note that the support for providing a package names XML document via command line option or as a attribute of an ant Checkstyle task has been dropped with Checkstyle 5.0.
A package names XML document specifies a list of
package names. Here is a sample package names XML document for
packages
com.puppycrawl.tools.checkstyle
and
com.puppycrawl.tools.checkstyle.checks
:
<checkstyle-packages> <package name="com.puppycrawl.tools.checkstyle"> <package name="checks"/> </package> </checkstyle-packages>
Notice that the packages are specified recursively - a child
package
element is a subpackage of its
parent package
element.
For example, to incorporate modules from package com.mycompany.checks
with Checkstyle
modules, create the XML file below and put this file into the
root of the jar file which contains your custom check modules.
The XML file must be named exactly checkstyle_packages.xml
:
<?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"/> </checkstyle-packages>
Now you can configure a module of package com.mycompany.checks
, say com.mycompany.checks.MethodLimitCheck
, with
a shortened module
element in the
configuration document:
<module name="MethodLimit"/>
As of Checkstyle 5.0 it is unnecessary to repeat the
package
elements for Checkstyle's packages in
your custom checkstyle_packages.xml
file.
The following DTD for a configuration XML document specifies the hierarchy of modules and their properties:
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT module (module|property)*> <!ATTLIST module name NMTOKEN #REQUIRED> <!ELEMENT property EMPTY> <!ATTLIST property name NMTOKEN #REQUIRED value CDATA #REQUIRED >
Checkstyle validates a configuration XML document when it loads the document. To validate against the above configuration DTD, include the following document type declaration in your configuration XML document:
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
Checkstyle also strictly enforces the encoding attribute of an XML declaration. If Checkstyle rejects your configuration document's encoding, correct the value of the encoding attribute, or remove the encoding attribute entirely.
For a complete example of a configuration XML document, examine
file docs/sun_checks.xml
that checks the Sun coding
conventions.
This is a DTD for a package names XML document:
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT checkstyle-packages (package)*> <!ELEMENT package (package)*> <!ATTLIST package name NMTOKEN #REQUIRED>
Checkstyle also validates a package names XML document when it loads the document. To validate against the above package names DTD, include the following document type declaration in your package names XML document:
<!DOCTYPE checkstyle-packages PUBLIC "-//Puppy Crawl//DTD Package Names 1.1//EN" "http://www.puppycrawl.com/dtds/packages_1_1.dtd">
This is a DTD for a suppressions XML document:
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT suppressions (suppress*)> <!ELEMENT suppress EMPTY> <!ATTLIST suppress files CDATA #REQUIRED checks CDATA #IMPLIED id CDATA #IMPLIED lines CDATA #IMPLIED columns CDATA #IMPLIED>