CS Plugin

Checkstyle is a great tool to ensure that coding in Java follows some rules.

Many standard checkers are provided in standard, but it is also possible to write new ones.

The goal of this place is to provide new (and sometimes experimental) checkers that will be hopfully one day integrated into Checkstyle.


Installation

  • Download the jar named cs.jar.
  • Choose which checker you want to use.
  • Modify the config.xml (you can find a example here).
  • Launch checkstyle with CS Plugin:
    java -classpath cs.jar:checkstyle-all-4.4.jar \
         com.puppycrawl.tools.checkstyle.Main \
         -c config.xml -r .

  • Checker Summary
    AvoidNegativeLogic This checker avoid the usage of inverted logic.
    AvoidSelfAssignement This checker detects variable that are assigned to itself.
    AvoidSingleton Singleton without any field are really useless.
    CanonicalFor This checker tries to detect inconsistence into for loop.
    CollapseIfStatement This checker looks for if statement with can be simplified.
    DeclareVariableInItsBloc Variable should be declared in the bloc that uses it.
    DuplicateBranche This checker detects branches that are exactly the same.
    DuplicateCondition This checker detect useless duplicated test.
    HiddenCatchBloc Very often, people catch exception and do not use the exception itself.
    ImmutableField This checker detects private fields that are unused in a class and promotes the usage of final for fields that are never changed.
    ImportControl This check control that import are valid into a java file, depending on its package.
    InstanceofIsNeverNull When an object is an instanceof something, it cannot be null.
    MisspelledIdent This checker looks for misspelled ident in source code.
    NewIsNeverNull When an object is created with new, it is never null.
    PatternFilter This filter looks like SuppressionFilter, but the configuration is done in the filter itself, and not into another XML file.
    PotentialNPE This checker tries to find some trivial NullPointerException.
    ReturnZeroLengthArray Return a zero length array instead of returning null.
    TooEarlyVariableDeclaration This checker try to detect too early variable declaration.
    UnitTestMethods This checker is really great for Test Driven Developpement.
    UnnecessarilyElse This checker detects unnecessarily else statement.
    UnnecessaryParentheses This checker detects some unnecessary parentheses which are not detected by the standard check of CheckStyle.
    UnusedImports Patched version of the standard UnusedImport.
    UnusedLocalVariable This checker detects unused local variable.
    UnusedPrivateMethod This checker looks for unused private method in a class.

    AvoidNegativeLogic

    This checker avoid the usage of inverted logic. It looks for code like :

     if (a != null) {
            System.out.println("not null");
     } else {
            System.out.println("null");
     }
     
    and promotes the usage of :
     if (a == null) {
            System.out.println("null");
     } else {
            System.out.println("not null");
     }
     

    AvoidSelfAssignement

    This checker detects variable that are assigned to itself.

    This is likely a typo. Example:

            this.foo = this.foo

    AvoidSingleton

    Singleton without any field are really useless. Not yet implemented

    CanonicalFor

    This checker tries to detect inconsistence into for loop.

    For example, if the variable declared in the initialisation is not used in the condition.


    CollapseIfStatement

    This checker looks for if statement with can be simplified.
    Up to now, it only deals with ==, !=, && and ||

    For example:

     if (a != null) {
            if (b == null) {
                    System.err.println();
            }
     }
     
    Can be simplified in:
     if (a != null && b == null) {
            System.err.println();
     }
     
    Another example:
     if (a == null) {
            // some code
     } else {
            if (b == null) {
                    // Some other code
            }
     }
     
    Can be simplified in:
     if (a == null) {
            // some code
     } else if (b == null) {
            // Some other code
     }
    

    DeclareVariableInItsBloc

    Variable should be declared in the bloc that uses it.

    For example:

     Object dummy;
     for (Iterator it = list.iterator(); it.hasNext();) {
            dummy = it.next();
            ...
     }
     (dummy not used anymore)
     
    Can be changed in:
     for (Iterator it = list.iterator(); it.hasNext();) {
            Object dummy = it.next();
            ...
     }
     

    DuplicateBranche

    This checker detects branches that are exactly the same. This probably means that there is a typo in the code.

    Example:

     if (a > 0) {
            b = 9;
     } else {
            b = 9;
     }
     
    Or:
     
     switch (a) {
            case 1: b = 15; break;
            case 2: b = 15; break;
     }
    

    DuplicateCondition

    This checker detect useless duplicated test. Example:

            if (getText() > 1 && getText() > 1) ...
     

    HiddenCatchBloc

    Very often, people catch exception and do not use the exception itself.

    Example:

     try {
            ...
     } catch (IOException e) {
            return null;
     }
     
    May be we should at least log the exception:
     try {
            ...
     } catch (IOException e) {
            log.error("IOError ", e);
            return null;
     }
     

    ImmutableField

    This checker detects private fields that are unused in a class and promotes the usage of final for fields that are never changed.

    By default log and serialVersionUID is ignored, but you can change this in the configuration file:

     <module name="cs.ImmutableField">
            <property name="ignore" value="(log|serialVersionUID|special.*)$" />
     </module>
    
     

    ImportControl

    This check control that import are valid into a java file, depending on its package.

    Example, to control that classes into com.foo2 (and subpackages) does not import com.foo1:

     <module name="cs.ImportControl">
            <property name="importThis" value="com\.foo1" />
            <property name="notByPackages" value="com\.foo2" />
     </module>
    
     

    Another example, to control that only classes into com.dummy2 (and subpackages) does import com.dummy1:

     <module name="cs.ImportControl">
            <property name="importThis" value="com\.dummy1" />
    
            <property name="onlyByPackages" value="com\.dummy2" />
     </module>
     

    InstanceofIsNeverNull

    When an object is an instanceof something, it cannot be null.

    So the following code :

    if (obj != null && obj instanceof List) {...} 
    should be changed into:
    if (obj instanceof List) {...}

    MisspelledIdent

    This checker looks for misspelled ident in source code.

    For example, hashcode or hascode is considered as a bad spelling of hashCode. The property correctIdents which default value is hashCode,equals,compareTo can be changed in the configuration file:

     <module name="cs.MisspelledIdent">
            <property name="correctIdents" value="hashCode,equals,compareTo,hasCode" />
     </module>

    NewIsNeverNull

    When an object is created with new, it is never null.

    So the following code :

     MyClass obj = new MyClass();
     if (obj != null) {
            // Some code
     }
     
    should be changed into:
     MyClass obj = new MyClass();
     // Some code
     

    PatternFilter

    This filter looks like the standard SuppressionFilter, but the configuration is done in the filter itself, and not into another XML file.

     <module name="Checker">
            <module name="cs.PatternFilter">
                    <property name="ignoreFiles"
                            value="(.*(&lt;=Managed)(&lt;=View)Bean\.java)|(.*Home\.java)" />
                    <property name="modules" value="TabCharacter|WhitespaceAround" />
            </module>
    
            <module name="TreeWalker">
                    ...
            </module>
     </module>
    

    PotentialNPE

    This checker tries to find some trivial NullPointerException. If a private method contains a "return null" statement, and if the result of this method is used without being tested against null, the checker log a error.

    This is quite experimental.


    ReturnZeroLengthArray

    Return a zero length array instead of returning null.

    When a method returns an array, it is often more logical to do:

     public String[] getFoo() {
            if (...) {
                    return new String[0];
            }
            ...
     }
     
    instead of :
     public String[] getFoo() {
            if (...) {
                    return null;
            }
            ...
     }
    

    TooEarlyVariableDeclaration

    This checker try to detect too early variable declaration.

    int i = 0, j = 4; // Error: Declare variables on separate lines

    int i;
    i = 4; // those two lines can be merged into "int i = 4"

    int i = 0; // this affectation is useless
    i = 4;

    int i; // Declare variable as close as possible to where they are used
    [...A lot of code that does NOT use i...]
    i = 6;


    UnitTestMethods

    This checker is really great for Test Driven Developpement. It checks that every non private method of a class is tested with JUnit 3.

    Example of module configuration:

     <module name="cs.UnitTestMethods">
            <property name="severity" value="warning" />
            <property name="filesToCheck"
                    value="(.*[/\\])src([/\\]dummy[/\\]\w+)\.java$" />
            <property name="testCases"
                    value="$1test$2Test.java" />
            <property name="minSemicolon"
                    value="2"/>
    
            <!-- method with less than 2 semicolons are too simple to be tested -->
     </module>
     
    This example looks for every Java file in src/dummy or src\dummy. The TestCase must be in test/dummy directory. Indeed, the testCases property is a pattern applied to retrieve the name of the TestCase. In the previous example, we just replace the src by test and we add Test to the java filename.

    The test method is considered correct if :


    UnnecessarilyElse

    This checker detects unnecessarily else statement. Example:

     if (a==null) {
            // some code
            return null;
     } else {
            // other things
     }
     
    which can be changed into:
     if (a==null) {
            // some code
            return null;
     }
     // other things
     
     

    UnnecessaryParentheses

    This checker detects some unnecessary parentheses which are not detected by the standard check of CheckStyle. Up to now, it only deals with ==,!=,&& and ||

    It detects the following code:

    ((a==null) && (b!=null))
    which is better read this way (except for people coming from LISP :-)
    (a==null && b!=null)

    UnusedImports

    Patched version of the standard UnusedImport. I've got a bug in Eclipse: when using "Organize Import", if a class is used into a "@see" statement only, Eclipse add it into the import list. But afterwards, CheckStyle complains about this unused import (which is correct).

    So I've patched the standard UnusedImport, and added a method isSeeOrThrowJavadocTag()


    UnusedLocalVariable

    This checker detects unused local variable. The detection is not 100% accurate.


    UnusedPrivateMethod

    This checker looks for unused private method in a class.

    It is not 100% accurate, since it can be confused if severals methods have the same name, but not the same number of arguments. It can also be confused if two methods have the same name in two differents classes.


    Example of config.xml file

    
    <?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">
    
    	<!-- Filtering some log message using cs.PatternFilter -->
    	<module name="cs.PatternFilter">
    		<property name="ignoreFiles"
    			value="^src\\cs\\(Avoid|Col)\w+.java" />
    		<property name="modules" value="cs\.NewIsNeverNull" />
    	</module>
    
    
    	<module name="TreeWalker">
    		<!-- Some standard Checker -->
    		<module name="LocalFinalVariableName" />
    		<module name="LocalVariableName" />
    		<module name="MemberName" />
    		<module name="MethodName" />
    		<module name="PackageName">
    
    		<!-- Some csplugin Checker -->
    		<module name="cs.CollapseIfStatement" />
    		<module name="cs.AvoidNegativeLogic" />
    		<module name="cs.DeclareVariableInItsBloc" />
    		<module name="cs.TooEarlyVariableDeclaration" />
    		<module name="cs.UnusedLocalVariable" />
    		<module name="cs.InstanceofIsNeverNull" />
    		<module name="cs.NewIsNeverNull" />
    		<module name="cs.UnnecessarilyElse" />
    		<module name="cs.HiddenCatchBloc" />
    		<module name="cs.UnusedImports" />
    
    	</module>
    
    </module>