Tuesday, August 2, 2011

Setup Maven checkstyle plugin

When your project start to grow and new developers join your team you need keep your project from turning into a mess. One of steps to avoid it - bringing style conventions. In this post I will describe how to setup a Maven plugin that checks style of your project's code. Installing and configuring should take no more than three hours.

In your pom.xml file you can specify number of plugins to collect report about you project. To see reports about checkstyle conventions violations you need to add two plugins: maven-jxr-plugin, and maven-checkstyle-plugin.

 <build>  
     <plugins>  
       <plugin>  
         <groupId>org.apache.maven.plugins</groupId>  
         <!-- Plugin that gives ability to generate your projects site -->  
         <artifactId>maven-site-plugin</artifactId>  
         <version>3.0-beta-2</version>  
         <configuration>  
           <!-- Reports that will be displayed on a generated site -->  
           <reportPlugins>  
             <!-- Produces a cross-reference of the project's sources. This is useful  
                for other reports like PMD or Checkstyle. When this plugin is used with  
                checkstyle you can see code that produces style warning/error in the report. -->  
             <plugin>  
               <groupId>org.apache.maven.plugins</groupId>  
               <artifactId>maven-jxr-plugin</artifactId>  
               <version>2.1</version>  
               <configuration>  
                 <aggregate>true</aggregate>  
               </configuration>  
             </plugin>  
             <!-- Checks projects code conventions -->  
             <plugin>  
               <groupId>org.apache.maven.plugins</groupId>  
               <artifactId>maven-checkstyle-plugin</artifactId>  
               <version>2.6</version>  
               <configuration>  
                 <configLocation>check_style.xml</configLocation>  
               </configuration>  
             </plugin>  
           </reportPlugins>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  

If you want to use style conventions check in all subprojects, you need to add it to the parent pom.xml of your project

Configuration of a code convention is placed in a separate file "check_style.xml" (just place to the directory with a pom.xml file). You can add more report plugins: for reporting test coverage or possible bugs.

Checkstyle plugin configuration is pretty straitforward. You need to define modules that are used for code conventions checking. Configuration of modules is done by adding submodules. In example bellow you can see an example of a simple configuration.

 <module name="Checker">  
   <module name="JavadocPackage"/>  
   <module name="TreeWalker">  
     <module name="AvoidStarImport"/>  
     <module name="ConstantName"/>  
     <module name="EmptyBlock"/>  
   </module>  
 </module>  

Now let's try to implement some real code conventions. Let's take code conventions from my favorite Java project: Java PathFinder :
  • 2 space indentation (no tabs)
  • opening brackets in same line (class declaration, method declaration, control statements)
  • no spaces after opening '(', or before closing ')'
  • method declaration parameters indent on column
  • all files start with copyright and license information
  • all public class and method declarations have preceding Javadoc comments
  • we use camelCase instead of underscore_names for identifiers
  • type names are upper case 

And here is Maven checkstyle configuration:

 <?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">  
   <!-- Following interprets the header file as regular expressions. -->  
   <module name="RegexpHeader">  
     <property  
       name="header"  
       value="^// JPF source file licence (\d\d\d\d)? By NASA$"/>  
   </module>  
   <!-- Checks that there are no tab characters ('\t') in the source code. -->  
   <module name="FileTabCharacter">  
     <!-- Report on each line in each file -->  
     <property name="eachLine" value="true"/>  
   </module>  
   <module name="TreeWalker">  
     <!-- No EOL should be placed before block start ('{') -->  
     <module name="LeftCurly">  
       <property name="option" value="eol"/>  
       <property name="severity" value="error"/>  
     </module>  
     <!-- '}' rules -->  
     <module name="RightCurly">  
       <!-- '}' should be on the same line as a next statement -->  
       <property name="option" value="same"/>  
       <property name="severity" value="error"/>  
     </module>      
     <!-- Braces are mandatory around code blocks -->  
     <module name="NeedBraces">  
       <property name="severity" value="error"/>  
     </module>  
     <!-- Checks the Javadoc of a method or constructor. -->  
     <module name="JavadocMethod">  
       <!-- Check for JavaDoc only on public methods -->  
       <property name="severity" value="error"/>  
       <property name="scope" value="public"/>  
     </module>  
     <!-- Checks Javadoc comments for class and interface definitions. -->  
     <module name="JavadocType">  
       <!-- Check for JavaDoc only on public types -->  
       <property name="scope" value="public"/>  
       <property name="severity" value="error"/>  
     </module>  
     <!-- Checks for Naming Conventions.              -->  
     <!-- See http://checkstyle.sourceforge.net/config_naming.html -->  
     <!-- Sun Naming Conventions -->  
     <module name="ConstantName"/>  
     <module name="LocalFinalVariableName"/>  
     <module name="LocalVariableName"/>  
     <module name="MemberName"/>  
     <module name="MethodName"/>  
     <module name="PackageName"/>  
     <module name="ParameterName"/>  
     <module name="StaticVariableName"/>  
     <module name="TypeName"/>  
     <!-- Checks correct indentation of Java Code. -->  
     <module name="Indentation">  
       <!-- how many spaces to use for new indentation level -->  
       <property name="basicOffset" value="2" />  
       <!-- how far brace should be indented when on next line -->  
       <property name="braceAdjustment" value="0"/>  
       <!-- how much to indent a case label -->  
       <property name="caseIndent" value="2"/>  
     </module>  
     <!-- Specify method parameters code conventions -->  
     <module name="MethodParamPad">  
       <!-- Whitespace is required after method name -->  
       <property name="option" value="space" />  
       <!-- Check only methods and constructors declarations -->  
       <property name="tokens" value="METHOD_DEF, CTOR_DEF" />  
     </module>  
     <!-- Checks the policy on the padding of parentheses; i.e. whether a space is required after a left parenthesis and before a  
        right parenthesis, or such spaces are forbidden. -->  
     <module name="ParenPad">  
       <!-- Whitespace required before ')' and after ')' -->  
       <property name="option" value="space"/>  
     </module>  
   </module>  
 </module>  

As you can see, all you need to do to configure checkstyle is to add correct modules and specify properties that you need. Checkstyle can do even more it can search for code duplication, produce error when you write bad Java code (while it can be very pretty). You can find all modules that can be used in checkstyle here.

There is no surprise, that you can also develop your own modules for Checkstyle.

Now let's check what we've done. Here I wrote a code that violates JPF conventions:
 package temp;  
 public class main {  
  /**  
   * this is my public method example  
   */  
  public void FFoo(int arg1, int arg2, int arg3) {  
   if (false)  
   {  
     System.out.println("if");  
   }  
   else  
   {  
     System.out.println("else");  
   }  
  }  
 }  

There is no JavaDoc on a class, class name and method name violates code conventions, no whitespace after method name, wrong '{' and '}' positions and so on.

Let's take a look at how checkstyle works. Just do this at one of your Maven sub-projects directory:
 > mvn site  
 [INFO] Scanning for projects...  
 [INFO]                                       
 [INFO] ------------------------------------------------------------------------  
 [INFO] Building Checkstyle 1.0  
 [INFO] ------------------------------------------------------------------------  
 [INFO]   
 [INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ Checkstyle ---  
 [INFO] Deleting /home/proger/Temp/Checkstyle/target  
 ...  
 [INFO]   
 [INFO] There are 21 checkstyle errors.  
 [INFO] ------------------------------------------------------------------------  
 [INFO] BUILD SUCCESS  
 [INFO] ------------------------------------------------------------------------  
 [INFO] Total time: 15.438s  
 [INFO] Finished at: Wed Aug 03 09:37:04 EEST 2011  
 [INFO] Final Memory: 18M/137M  

When site with reports is created we need to open target/site/checkstyle.html in browser.

We will see:

Here is a list of errors that were found in project's code:

That's all.
Good luck.

2 comments:

  1. Thanks Ivan Mushketik,

    It working for me. Thanks.

    ReplyDelete
  2. Casino - Bracket betting guide for your chance to win
    The Casino is a unique casino that has been around gri-go.com for over a decade. It https://deccasino.com/review/merit-casino/ has managed https://deccasino.com/review/merit-casino/ to offer great games such as Blackjack, Roulette and Video Poker, titanium earrings

    ReplyDelete