Checkstyle – Enforce coding rules and styles across android projects

By -

From Documentation:

Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard. It automates the process of checking Java code to spare humans of this boring (but important) task. This makes it ideal for projects that want to enforce a coding standard.

Based on my experience of working on different projects and different teammates, I have observed most of all the programmers are having their own style of writing code, whether it’s upto the standard or not but yes they would come to learn based on the experience, but still you would not be sure about the same style/pattern/standards they follow across projects!

At Lets Nurture, code review is getting done, completely manually but now we are focusing more onto automate certain things which we can! To do so, there is a challenge which is to check whether code has been implemented as per the styles and standards! (We should not go and check whether unused imports in each project files!). At least we can automate it and for the same, we have started integrating tools which can help us to automate such things. We have integrated couple of tools in android develpment, one of them is Checkstyle, more about other tools in coming articles!

Now, let’s see how we can configure it for the android application.

ALERT: When you integrate checkstyle in android project, initially you would find it boring and difficult!

How it works?

We need to include one checkstyle.xml (i.e. configuration file) into the project and configure it using task in gradle file. So whenever we build project, it performs check (with those rules defined in that configuration file) on written java code, fails build and give errors as soon as it found something broken!

To perform checkstyle rules in Android studio, we have to define a task and configure the same into the gradle build system. Later in this article, we will see what to define and how to configure!

Output

As I mentioned above, it shows error and stops build as soon as it detects some code found against the defined rules in checkstyle.xml file.

checkstyle-warnings

Checkstyle also gives reports in html format.

checkstyle-warning-_-html-reports

checkstyle-warning-_-html-reports

Checkstyle configuration demo file

Below is the configuration demo file which I have used in recent projects. The popular OkHttp library also has a checkstyle configured, check and take reference from https://android.googlesource.com/platform/external/okhttp/+/jb-mr1-dev/checkstyle.xml

<?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">
    <module name="NewlineAtEndOfFile"/>
    <module name="FileLength"/>
    <module name="FileTabCharacter"/>

    <!-- Trailing spaces -->
    <module name="RegexpSingleline">
        <property name="format" value="\s+$"/>
        <property name="message" value="Line has trailing spaces."/>
    </module>

    <module name="TreeWalker">
        <property name="cacheFile" value="${checkstyle.cache.file}"/>

        <!-- Checks for Javadoc comments.                     -->
        <!-- See http://checkstyle.sf.net/config_javadoc.html -->
        <!--module name="JavadocMethod"/-->
        <!--module name="JavadocType"/-->
        <!--module name="JavadocVariable"/-->
        <module name="JavadocStyle"/>


        <!-- Checks for Naming Conventions.                  -->
        <!-- See http://checkstyle.sf.net/config_naming.html -->
        <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 for imports                              -->
        <!-- See http://checkstyle.sf.net/config_import.html -->
        <module name="AvoidStarImport"/>
        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
        <module name="RedundantImport"/>
        <module name="UnusedImports"/>


        <!-- Checks for Size Violations.                    -->
        <!-- See http://checkstyle.sf.net/config_sizes.html -->
        <module name="LineLength">
            <property name="max" value="120"/>
        </module>
        <module name="MethodLength"/>
        <module name="ParameterNumber"/>


        <!-- Checks for whitespace                               -->
        <!-- See http://checkstyle.sf.net/config_whitespace.html -->
        <module name="GenericWhitespace"/>
        <module name="EmptyForIteratorPad"/>
        <module name="MethodParamPad"/>
        <module name="NoWhitespaceAfter"/>
        <module name="NoWhitespaceBefore"/>
        <module name="OperatorWrap"/>
        <module name="ParenPad"/>
        <module name="TypecastParenPad"/>
        <module name="WhitespaceAfter"/>
        <module name="WhitespaceAround"/>


        <!-- Modifier Checks                                    -->
        <!-- See http://checkstyle.sf.net/config_modifiers.html -->
        <!--module name="ModifierOrder"/-->
        <module name="RedundantModifier"/>


        <!-- Checks for blocks. You know, those {}'s         -->
        <!-- See http://checkstyle.sf.net/config_blocks.html -->
        <module name="AvoidNestedBlocks"/>
        <!--module name="EmptyBlock"/-->
        <module name="LeftCurly"/>
        <module name="NeedBraces"/>
        <module name="RightCurly"/>


        <!-- Checks for common coding problems               -->
        <!-- See http://checkstyle.sf.net/config_coding.html -->
        <!--module name="AvoidInlineConditionals"/-->
        <module name="CovariantEquals"/>
        <module name="DoubleCheckedLocking"/>
        <module name="EmptyStatement"/>
        <!--<module name="EqualsAvoidNull"/>-->
        <module name="EqualsHashCode"/>
        <!--module name="HiddenField"/-->
        <module name="IllegalInstantiation"/>
        <!--module name="InnerAssignment"/-->
        <!--module name="MagicNumber"/-->
        <!--module name="MissingSwitchDefault"/-->
        <module name="RedundantThrows"/>
        <module name="SimplifyBooleanExpression"/>
        <module name="SimplifyBooleanReturn"/>

        <!-- Checks for class design                         -->
        <!-- See http://checkstyle.sf.net/config_design.html -->
        <!--module name="DesignForExtension"/-->
        <module name="FinalClass"/>
        <module name="HideUtilityClassConstructor"/>
        <module name="InterfaceIsType"/>
        <!--s/module name="VisibilityModifier"/-->


        <!-- Miscellaneous other checks.                   -->
        <!-- See http://checkstyle.sf.net/config_misc.html -->
        <module name="ArrayTypeStyle"/>
        <!--module name="FinalParameters"/-->
        <!--module name="TodoComment"/-->
        <module name="UpperEll"/>
    </module>
</module>

Configure checkstyle.xml for android application

Follow below steps for integrating checkstyle.xml in the android application project.

Step 1: Create checkstyle.xml file in settings folder at root level

Create a checkstyle.xml file and put it inside the settings (or configure) directory at root level of the project. Copy the checkstyle rules from the given demo configuration file above and paste it into your checkstyle.xml configuration file.

Step 2: Define checkstyle task in gradle (root level)

allprojects {
   repositories {
       jcenter()
   }
 
   task checkstyle(type: Checkstyle) {
       showViolations = true
       configFile file("../settings/checkstyle.xml")
 
       source 'src/main/java'
       include '**/*.java'
       exclude '**/gen/**'
       exclude '**/R.java'
       exclude '**/BuildConfig.java'
 
       // empty classpath
       classpath = files()
   }
}

Step 3: Apply checkstyle plugin and use the defined checkstyle task in module level build.gradle file

apply plugin: 'checkstyle'
 
preBuild.dependsOn('checkstyle')
assemble.dependsOn('lint')
check.dependsOn('checkstyle')

Download example project

You can download the example project to check how it works. Download from https://github.com/PareshMayani/CheckstyleDemo

Source

In Summary

This has brought to the end of this article. In this article, we have talked about checkstyle plugin, configuring the same for android application projects and how it can help us to maintain the coding styles and standards. As I mentioned, initially it would be boring and headache but gradually you would be habitual to write code as per the configuration defined in checkstyle configuration file.

If time permits then will talk about such tools which we have integrated for the android project! Until then keep sharing and learning together :)

Originally posted on Checkstyle – Enforce coding rules and styles across android projects

Paresh Mayani

Lazy android developer, exploring the horizon of android development since 7 years. He is Technical Lead - Android at Lets Nurture, India. He is also Application Architect at KarConnect. He is the Head/Organizer of Google Developers Group (GDG), Ahmedabad

Loading Facebook Comments ...
Loading Disqus Comments ...