Checkstyle Core Engine - Version 3.0

Authors: Oliver Burn, Lars K?hne

Introduction

This document describes the core engine of Checkstyle, including what checks it performs and what can be configured. The engine can be executed via different interfaces. The standard distribution includes support for:

System Requirements

To run checkstyle you will need:

Checkstyle has been tested using:

What checkstyle checks

Checkstyle operates on a set of syntactically correct Java files. Checkstyle will report syntax errors, but the focus of the tool is not to provide perfect error messages for Java syntax errors - we leave that to the compiler vendors.

For each Java file, Checkstyle will check the following:

Imports

Checks for illegal package prefixes in import statements. The prefix sun is the default, since programs that contain direct calls to the sun.* packages are not 100% Pure Java.

Checks for import statements that are not used. It will warn about wild-card imports like import java.io.*;. It will also warn about duplicate import statements.

Removing unused import statements reduces unnecessary dependencies in a code base. This feature can be turned off.

Javadoc tags

Checks that the following constructs have a Javadoc comment:

You can require that a package.html file exists for each package. This check is turned off by default.

Javadoc comments for class and interface declarations are checked to ensure that the @author and @version tags exist. These checks can be turned on/off.

You can control the visibility scope where Javadoc comments are checked. For example, you can check Javadoc code only for public and protected variables, methods, interfaces and class definitions. Scoping rules apply, in the above example a public method in a package visible class is not checked. You can also completely turn off all checking for Javadoc comments.

Javadoc comments for methods are checked to ensure that the following tags exist (if required):

For example the following is valid:

    /**
     * Checks for a return tag.
     * @return the index of the next unchecked tag
     * @param aTagIndex the index to start in the tags
     * @param aTags the tags to check
     * @param aLineNo the line number of the expected tag
     **/
    public int checkReturnTag(final int aTagIndex,
                              JavadocTag[] aTags,
                              int aLineNo)

By default an unused @throws tag is reported as error. It is possible to enable checking to determine if the exception is a subclass of java.lang.RuntimeException. This supports the convention in the Sun Javadoc Guidelines and the "Effective Java" book. By default the check is off as it requires the classpath to be configured.

Tip

It can be extremely painful writing or duplicating Javadoc for a method required for an interface. Hence checkstyle supports using the convention of using a single @see tag instead of all the other tags. For example, if the previous method was implementing a method required by the com.puppycrawl.tools.checkstyle.Verifier interface, then the Javadoc could be done as:

    /** @see com.puppycrawl.tools.checkstyle.Verifier **/
    public int checkReturnTag(final int aTagIndex,
                              JavadocTag[] aTags,
                              int aLineNo)

Curly Braces

Checks for the correct placement of left curly braces '{'. The check can be configured with the following options:

Option Definition
ignore Ignore the placement of the brace.
eol The brace must always be at the end of the line. For example:
    if (condition) {
        ...
This is the default value.
nl The brace must always be on a new line. For example:
    if (condition)
    {
        ...
nlow If the brace will fit on the first line of the statement, taking into account maximum line length, then apply eol rule. Otherwise apply the nl rule. nlow is a mnemonic for "new line on wrap". For the example above Checkstyle will enforce:
    if (condition) {
        ...
But for a statement spanning multiple lines, Checkstyle will enforce:
    if (condition1 && condition2 &&
        condition3 && condition4)
    {
        ...

The check can be tailored for types, methods and others. What is included in others are the keywords switch, while, for, do, if, else, synchronized, try, catch, finally and static.

There is also a check for the correct placement of right curly braces '}' with the keywords else, catch and finally. The check can be configured with the following options:

Option Definition
ignore Ignore the placement of the brace.
same The brace must be on the same line as the next statement. For example:
    try {
        ...
    } finally {
This is the default value.
alone The brace must be alone on the line. For example:
    try {
        ...
    }
    finally {

Long Lines

Checks for lines that are longer than a specified length. The default is "80". This can be turned off for import statements or for lines that match a regular expression.

Method Body Length

Checks for method bodies that are longer than a specified number of lines. The lines are counted from the opening brace '{' to the closing brace '}'. The default is "150".

Constructor Body Length

Checks for constructor bodies that are longer than a specified number of lines. The lines are counted from the opening brace '{' to the closing brace '}'. The default is "150".

File Length

Checks for files that are longer than a specified number of lines. The default is "2000".

Tab characters

Checks for lines that contain tab ('\t') characters. This can be turned off.

Number of parameters

Checks for the number of parameters in a declaration being greater than a specified amount. The default is "7".

To-do comments

Checks for comments that contain a specified regular expression. The default is "TODO:".

Format of variable names

Verifies that the format of the variable names conform to a specified regular expression. The formats can be overridden. The following table outlines the defaults:

Scope Default Format Example
Constants (static and final) ^[A-Z](_?[A-Z0-9]+)*$
The exception to the rule is for serialVersionUID.
public static final int MAX_ROWS = 2;
Static variables (static only) ^[a-z][a-zA-Z0-9]*$ private static int numCreated = 0;
Members (non static) ^[a-z][a-zA-Z0-9]*$ private int mySize = 0;
Public members (non static public) ^f[A-Z][a-zA-Z0-9]*$ public int fCMPField;

The default values prior to release 1.4 were:

Scope Old Format
static only ^s[A-Z][a-zA-Z0-9]*$
non static ^m[A-Z][a-zA-Z0-9]*$

Format of parameter names

Verifies that the format of parameter names conform to a specified regular expression. The default is ^[a-z][a-zA-Z0-9]*$. The default value prior to release 1.4 was ^a[A-Z][a-zA-Z0-9]*$.

Format of type names

Verifies that the format of class and interface names conform to a specified regular expression. The default is ^[A-Z][a-zA-Z0-9]*$.

Format of public member names

Verifies that the format of public member names conform to a specified regular expression. The default is ^f[A-Z][a-zA-Z0-9]*$. This is useful for the fields required for Container Managed Persistence (CMP) Enterprise JavaBeans 1.1.

Format of method names

Verifies that the format of method names conform to a specified regular expression. The default is ^[a-z][a-zA-Z0-9]*$.

Format of local variable names

Verifies that the format of local variables conform to a specified regular expression. The default is ^[a-z][a-zA-Z0-9]*$.

Integer Literals

Verifies that long integer literals use an uppercase L. For example 40L instead of 40l. This is in accordance to the Java Language Specification, Section 3.10.1. This check can be turned off.

Modifiers

Checks that the order of modifiers conforms to the suggestions in the Java Language specification, sections 8.1.1, 8.3.1 and 8.4.3. The correct order is public protected private abstract static final transient volatile synchronized native strictfp.

Checks that method declarations in interfaces do not include the public or abstract modifiers, see the Java Language specification, section 9.4.

Visibility Modifiers

Checks for data members that are not declared private. Also finds static non-final data members that are not declared as private.

Note: you can turn on allowing protected or package visible data members.

Tip

Container Managed Persistence EJBs require (in the EJB 1.1 specification) that managed fields are declared public. This will cause checkstyle to complain that the fields should be declared private. Hence checkstyle supports ignoring public that match a specified regular expression. The default is ^f[A-Z][a-zA-Z0-9]*$.

White space

Checks for the following use of white space:

This feature can be turned off.

The options for specifying how to pad parenthesises are:

Option Definition
ignore Ignore the padding.
nospace Do not pad. For example, method(a, b);
space Ensure padding. For example, method( a, b );

Line wrapping on operators

Check for wrapping lines on operators. The check can be configured with the following options:

Option Definition
ignore Ignore wrapping on an operator.
nl The operator must be on a new line. For example:
    someVariable = aBigVariableNameToMakeThings + "this may work"
                   + lookVeryInteresting;
This is the default value.
eol The operator must be at the end of the line. For example:
    someVariable = aBigVariableNameToMakeThings + "this may work" +
                   lookVeryInteresting;

Missing Braces

Checks for missing braces {}'s for the following constructs:

This feature can be turned off.

File Header

Ensure that the file starts with a specified header. The header contents are specified in a file. If no file is specified, checkstyle does not check for a header.

Tip

Most copyright headers will contain date information (for example the year) which will change over time. To support this, checkstyle supports specifying the lines in the header to ignore when comparing the start of the file with the header. For example, consider the following header:

line 1: ///////////////////////////////////////////////////////////////////////
line 2: // checkstyle: Checks Java source code for adherence to a set of rules.
line 3: // Copyright (C) 2001  Oliver Burn
line 4: ///////////////////////////////////////////////////////////////////////

Since the year information will change over time, you can tell checkstyle to ignore line 3.


Tip

Checkstyle also supports interpreting each header line as a regular expression. For example, consider the following header when regular expression checking is turned on:

line 1: /{71}
line 2: // checkstyle: Checks Java source code for adherence to a set of rules\.
line 3: // Copyright \(C\) \d\d\d\d  Oliver Burn
line 4: // Last modification by \$Author.*\$
line 5: /{71}

Lines 1 and 5 demonstrate a more compact notation for 71 '/' characters. Line 3 enforces that the copyright notice includes a four digit year. Line 4 is an example how to enforce revision control keywords in a file header.

Empty Blocks

Checks for empty try, catch, finally blocks. The checks can be configured with the following options:

Option Definition
ignore Ignore empty blocks.
text Require that there is some text in the block. For example:
    catch (Exception ex) {
        // This is a bad coding practice
    }
This is the default value.
stmt Require that there is a statement in the block. For example:
    finally {
        lock.release();
    }

Instantiations

Checks for instantiation of classes that should not be instantiated directly. The list of these classes is configurable, the default is that all instantiations are legal.

Tip

A common mistake is to create new instances of java.lang.Boolean instead of using the constants TRUE and FALSE or the Boolean.valueOf() factory methods. This increases the program's memory requirements and wastes CPU cycles during memory allocation and garbage collection.

To find this error automatically, include java.lang.Boolean in the list of illegal instantiations.

Output Format

The Checkstyle engine has a flexible output mechanism inspired by ANT. AuditEvent objects are generated (for found errors) and are consumed by listeners that implement the AuditListener interface.

The output messages are localised using resource bundles with the base name of com.puppycrawl.tools.checkstyle.messages. By default Checkstyle uses the system default locale, but it is possible to define the locale language and country codes to use. Help is requested is translating the messages used by Checkstyle. Please email us if you translate the messages to another language.

The standard distribution comes with the following listeners:

Tip

It is possible to specify a base directory which files are then reported relative to. For example, if a base directory is specified as c:\projects\checkstyle, then an error in the file c:\projects\checkstyle\src\dir\subdir\File.java will be reported as src\dir\subdir\File.java.


Copyright © 2001 Oliver Burn. All rights Reserved.