Writing Checkstyle rules with Android Studio

Liudas Survila
5 min readFeb 12, 2015

--

Checkstyle is a development tool that checks your java code with rules according to your coding standards. It is configurable using .xml file, where each module is a rule, which itself can be modified using properties and looks like this:

You can check API docs for what those rules mean.

Make sure to read official documentation on how to create custom rules for better understanding. Internally it’s using Visitor pattern by going through AST of your files. To better understand AST, download, use Checkstyle SDK GUI app on your source files and analyse them. Also it’s a good idea to look at source code of default rules.

Problem

While developing you’ve might stumbled into this Parcelable interface, which is required to be implemented for classes you wish to pass through Android IPC. One of the requirements is for your parcel class to have constant CREATOR, which is usually at the end of class (as it is a boilerplate code and shouldn’t bother developer). If you use Parcelable generator like parcelabler, you will have something like this:

And if you run checkstyle with DeclarationOrderCheck on you will get errors:

<file name=”/Users/survilal/Documents/Android Studio Projects/CheckstyleBuilder/app/src/main/java/com/lsurvila/checkstylebuilder/ParcelableExample.java”>
<error line=”6" severity=”warning” message=”Missing a Javadoc comment.” source=”com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck”/>
<error line=”36" column=”5" severity=”error” message=”Static variable definition in wrong order.” source=”com.puppycrawl.tools.checkstyle.checks.coding.DeclarationOrderCheck”/>
<error line=”36" column=”5" severity=”error” message=”Variable access definition in wrong order.” source=”com.puppycrawl.tools.checkstyle.checks.coding.DeclarationOrderCheck”/>
</file>

We get two errors:

  1. Static variables must be declared after other static ones. In other words they should be grouped together.
  2. More accessible variables must be defined first. In our case public (CREATOR) is defined after private ones.

Basically this rule checks if variables, methods and constructors are ordered correctly in a class according to Java Code Conventions.

Solution

You could of course move it to on top of every class, that uses this interface, but that is not cool, so instead we are going to create a new rule along with Checkstyle ‘builder’ Android project (for future custom rules). New rule will have same functionality as DeclarationOrderCheck, but with an optional boolean property ignoreParcelableCreator.

Run

  1. Create a new Android Studio Project. Add your Parcelable java file.
  2. Add your checkstyle.xml file somewhere in project like in {project}/config/checkstyle/
  3. In your main module’s (usually app) build.gradle apply checkstyle plugin and add checkstyle task. In task reference where you’ve put your config file:

4. To run simply execute command. You will see result in terminal and the location of report file.

 ./gradlew checkstyle 

Custom

Create a new java module (let’s say custom-checkstyle) and add dependency on checkstyle lib from maven repo.

Add dependency on your main module to use custom-checkstyle one like this:

Create new rule file (lets say AndroidDeclarationOrderCheck). As the original class is not very friendly to extend, we are going to copy it’s contents to our class, extend base Check class and modify where we need. To add a new property, all we need is to add appropriate setter along default ones and it will automatically work (it’s done internally using reflection):

Now to make this flag to work we are going to modify visitToken method, specifically when it’s checking for modifiers, more specifically when it’s checking for static and access order. These are the places where our parcelable creator fails:

So let’s add additional condition with our newly created flag and lets show error when current modifier is not a parcelable creator:

To better understand how isParcelableCreator method works, here is comparison between algorithm and actual AST of file opened with Checkstyle SDK GUI app:

Now replace DeclarationOrderCheck with our crated one in checkstyle.xml with a full path. Set the flag to true and it should pass, set it to false and it will fail again:

<file name=”/Users/survilal/Documents/Android Studio Projects/CheckstyleBuilder/app/src/main/java/com/lsurvila/checkstylebuilder/ParcelableExample.java”>
<error line=”6" severity=”warning” message=”Missing a Javadoc comment.” source=”com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck”/>
</file>

Reuse

Now to make our custom checkstyle reusable, we are going to jar it and put it alongside checkstyle.xml, where both can be easily moved to other projects. Let’s test it on the same project. First on custom-checkstyle module’s build.gradle override jar task and set it’s destination to config folder. Also it’s a good idea to set compiler java version, as it may give incompability errors if your default java is newer than 1.7 (which is not currently supported by Android):

Now every time you want to build new checkstyle lib to reuse, execute:

./gradlew :custom-checkstyle:jar

Jar should appear in {project}/config/checkstyle folder. Now in main module’s build.gradle instead of dependency on custom-checkstyle module add dependency on checkstyle lib from maven + jar (as by default our jar only contains our created files). And you should be able to run it same as before:

You can find full project on my github.

Finish

Checkstyle is a good way to keep everyone on team on same coding standards. It’s even better when you can create your own rules, especially when existing rules conflicts with a platform you are working on. Possible improvements: adding unit testing, also extracting checkstyle lib to your company maven repo. Approach in this blog post is not perfect, but it’s something. Keep your code clean ☺

References:

  1. Checkstyle official website
  2. Creating your own Checkstyle check (with maven)
  3. How to improve quality and syntax of you Android code

--

--

Liudas Survila

Android, Clean Code, Software Craftsmanship, UX, Fitness, Science