riting consistently clear, high quality, maintainable code is an art that requires a certain amount of discipline at the best of times. Coding standards lay out rules and recommendations about the way code should be written and also enshrine good coding habits. Recently, coding standards have enjoyed renewed importance and visibility in software development, as they have been promoted as a key best practice of agile development.
Checkstyle is an open-source tool that can help enforce coding standards and best practices. It can be used as a standalone tool to generate reports on overall code quality, and can also be incorporated into the developer’s work environment, providing real-time visual feedback about the code being written.
Coding Standards
Coding standards are a key best practice in many development processes, and for good reason. These standards codify (no pun intended) time-honored traditions and conventions, as well as best practices in the art of software writing. Some recommendations simply define a standard way to layout code or to name classes or variables, while others are designed to make code more reliable or better performing.
However, as Andrew S. Tanenbaum, professor of Computer Science at Vrije Universiteit, Amsterdam, and author of the Minix operating system, said, “The nice thing about standards is that there are so many to choose from.” Different companies, teams, and individual developers have developed different programming practices and habits over time. The problems start when developers who use different programming styles and conventions have to work together on a common code base.
Indeed, many standards, such as indentation and naming conventions, are fairly arbitrary things. Should the curly brackets go directly after the instruction, as recommended by the Sun coding conventions?
while (i < 10) { i++;}
Or should they be on a new line, as used by many C++ developers?
while (i < 10) { i++;}
There is no real objective reason to prefer one style over the other: the important thing is to have a well defined and accepted style within your project. Recognized coding standards help to harmonize the way a team or company works together. Once team members are familiar with an established set of coding standards, they will think less about details such as code layout and variable naming conventions and can concentrate better on the real work of coding. New project teams will lose less time at the start of a project making decisions of earth-shattering importance such as where to put the curly bracket after the if statement.
The consistent use of standards also encourages a feeling of 'esprit de corps' within a team or company. And code which is laid out consistently and which follows well-known conventions is easier to read, understand, and maintain.
Sun has defined a set of coding conventions for the Java language that are widely accepted in the industry. Many companies and open source projects also publish their own set of coding conventions, often variations of the Sun conventions. A few typical coding standards are given here:
- Comments:
- Write Javadoc comments for all classes, methods, and variables.
- Naming conventions:
- Class names should be nouns, in mixed case with the first letter of each internal word capitalized (MyClass).
- Variable names should be nouns, in mixed case with a lowercase first letter, and with the first letter of each internal word in upper case (myVariable).
- Constants should be in all uppercase with words separated by underscore (MY_CONSTANT_VALUE).
- Indentation:
- Spaces should be preferred to tabs for indenting purposes.
- Declarations:
- One declaration per line, with comments, for example:
int class; // The child's class, from 1 to 8int age; // The child's age
rather than:
int class, age;
- One declaration per line, with comments, for example:
- Statements:
- Opening braces in compound statements should be at the end of the line that begins the compound statement; the closing brace should begin a line and be indented to the beginning of the compound statement, for example:
while (i < 10) {i++;}
- Opening braces in compound statements should be at the end of the line that begins the compound statement; the closing brace should begin a line and be indented to the beginning of the compound statement, for example:
- Best practices:
- Use the final keyword for variables and parameters that will not need to be modified.
- Don't declare variables within loops
It is a good idea to discuss the conventions to be applied within your company or project with all members of the development team. Each rule should be explained and justified. What is the underlying goal of the rule? Is the rule to be applied systematically, or can there be exceptions? As with many best practices, coding standards must be well-understood by the whole team to be effective.
Getting Started with Checkstyle
Checkstyle is an open source tool that enforces coding conventions and best practice rules for Java code. It works by analyzing Java source code and reporting any breach of standards. It can be integrated into your favorite IDE via a plug-in, so that developers can immediately see and correct any breaches of the official standards. It can also be used to generate project-wide reports that summarize the breaches found.
Checkstyle comes out-of-the-box with the standard Sun conventions, including more than 120 rules and standards, dealing with issues that range from code formatting and naming conventions to EJB best practices and code complexity metrics. Checkstyle supports standards related to:
- Javadoc comments
- Naming conventions
- File headers
- Import statements
- White space
- Modifiers
- Blocks
- Coding problems
- Class design
- J2EE
- And other miscellaneous issues
Using Checkstyle from within Eclipse
Checkstyle can be used in a variety of ways, including from the command line or from within an Ant or Maven build script. However, the most efficient way to use it is from within the IDE, as corrections can be made immediately and with little effort. Plug-ins exist for most of the major Java IDEs, including Eclipse, IntelliJ, NetBeans, JBuilder, and even JEdit. Next I'll look at how this is done using Eclipse.
The Eclipse Checkstyle Plug-in is found at http://eclipse-cs.sourceforge.net/index.html. The first thing you will need to do is to install the plug-in. The simplest way to do this is to use the plug-in's Remote Update site (see Figure 1).
![]() Figure 1. Installing Checkstyle on Eclipse: Installing the Checkstyle plug-in for Eclipse using the remote update site is simple. | ? | ![]() Figure 2. Activating Checkstyle in an Eclipse Project: Checkstyle offers a plug-in for the Eclipse IDE as well as many others. |
Once the plug-in is installed, you can activate Checkstyle checks for your particular project (see Figure 2). Open the project properties window (Project->Properties), select the Checkstyle properties entry, make sure the 'Checkstyle active for this project' check box is ticked, and press OK. At this point, Checkstyle runs as a background task and audits the source code in your project. This may take some time, depending on the size of your project.
When Checkstyle finishes its audit, you will probably have a long list of standards violations, listed as warnings in the Problems view pane. Clicking on a problem in this list will automatically jump to the offending code segment.
The Checkstyle plug-in works in the same way as the Java compiler. Now, whenever you edit and save your Java classes in a Checkstyle-activated project, your code is automatically checked and any infringements are highlighted and explained (see Figure 3). They are rather hard to miss: the offending code is highlighted in yellow, with a corresponding marker in the margin for good measure.
In any project where coding standards are to be enforced, developers need to work with an IDE correctly configured with Checkstyle. If properly encouraged, they will come to consider coding standard errors almost in the same way as syntax errors, correcting their code as they write it. And the project standards will be gradually and smoothly adopted by all team members. This is by far the most efficient way of enforcing coding standards.
On the other hand, running Checkstyle on a large existing code base can be positively demoralizing, especially if no (or different) coding standards were previously enforced, as the number of errors can be overwhelming. This is an important factor when considering how to introduce coding standards into an organization.
In the next section, I'll look at how you can customize Checkstyle coding standards to your team's particular requirements.
![]() Figure 3. Checkstyle in Action: The Checkstyle Eclipse plug-in will remind many of a compiler; it steps through the code and highlights issues in yellow. | ? | ![]() Figure 4. Configuration: Here I'm creating a new configuration file that Checkstyle will add to its reference data. |
Customizing Coding Standards from within Eclipse
The Sun coding standards?provided "out-of-the-box" via a configuration file?can be overwhelming at times. Checkstyle may well come up with hundreds of relatively minor rule violations (white spaces at the ends of lines, for example), especially if a lot of code has already been written without Checkstyle in place. The more important standards may get lost in the mass of minor and relatively unimportant ones. This can result in two possible negative side-effects:
- Developers will become discouraged, and ignore all rule violations, which tends to defeat the purpose of installing Checkstyle in the first place.
- Developers will become overly zealous, and pass hours removing spaces from the ends of lines, and so forth. This will produce nice clean code, but will probably slow down developer productivity considerably.
To optimize the adoption of coding standards and the use of Checkstyle to enforce them, a more flexible approach is often needed. The easiest way to do this is to create a custom set of coding standards that is specifically designed either for your company or for a single project.
You can do this fairly easily from within Eclipse (see Figure 4). Go into the Preferences window, and select the Checkstyle preferences. You will see some built-in configuration files (the Sun coding standards and a slightly modified version of the Sun standards adapted to the default code formatting used by Eclipse).
To create a new Checkstyle configuration file, just click "New." Several types of configuration files are available, including:
- Built-in Configurations, for example, the Sun coding standards, which are delivered with the Checkstyle plug-in, and which cannot be altered.
- Internal Configurations, which are stored within the Eclipse metadata. These are useful for experimenting locally with new configurations, but cannot (easily) be shared with other team members.
- External Configurations, which are imported from an external source. External configurations may be imported from an external file on a local disk ("External Configuration"), or from a web server ("Remote Configuration"), or be stored within the Eclipse project, under configuration management, for example ("Project Relative Configuration").
Project Relative Configurations are particularly useful when the corresponding Checkstyle configuration file is also used in the build process by other tools such as Ant or Maven.
When you build a new set of coding standards, the simplest option is to start with an Internal Configuration, and then to export and publish it once you (and the rest of the team) are happy with it.
![]() | |
Figure 5. Customization: You can enforce custom styles and rules by creating your own Checkstyle configuration file. |
Configuring the Checkstyle configuration file using the plug-in is straightforward. When you click on the new configuration, you open a window displaying the available Checkstyle modules, along with those that have been activated for this configuration file (see Figure 5). To add a module to your configuration file, simply click on the module and configure it to your particular needs. Each module has its own specific configuration parameters.
It is important to get buy-in from your development team for any coding standards initiative. A good approach is to go through the list of standards with your team, discussing each one, and then to configure your module according to your project needs and standards. This helps developers understand the impetus behind each rule, which will encourage adoption.
Customizing Checkstyle Coding Standards in XML
Under the hood, a Checkstyle configuration file is a standard XML file which defines a set of modules that are to be used to verify source code. Each module is specialized in one particular kind of coding standard or best practice.
Modules are organized hierarchically: The root module is always the "Checker" module, which contains other modules. Modules can also contain sub-modules. This is notably the case of the "TreeWalker" module, which parses a Java source file and then lets sub-modules verify different aspects of the parse tree. In fact, the majority of Checkstyle modules are sub-modules of the "TreeWalker" module. Here is an excerpt from a simple Checkstyle configuration file:
Module behavior can be customized using properties. Each module has a set of properties with default values. To override a property, you just add a property tag in the body of the module tag. For example, for the "LineLength" module the default maximum line length is 80 characters. If you want to check for lines longer than 70 characters instead, you would set the "max" property, as follows:
The severity property can be applied to any module, and is used to determine the type of message that will be displayed. To deactivate a module, for example, set the severity to "ignore":
Most modules perform well using the default configuration. The "JavadocType" module checks class and interface Javadoc comments. To activate this module with the default values, you just declare the module in the configuration file (it must be nested inside the "TreeWalker" module):
By default the @author tag is not required. For your project or company, you may decide to make it mandatory. If so, you would also define the "authorFormat" property for this module as follows (in this case, any non-null string will do):
Many modules, such as naming conventions use regular expressions. For example, here is a stricter version of the package naming convention, where only lower-case letters and digits are authorized in package names:
Many companies and projects use a standard file header convention. Checkstyle offers many ways to enforce this. For simple cases, you can write a header template, where some lines are fixed and others may be modified by the developer. Suppose your company standards impose a boxed-style comment with a copyright line at the bottom, as shown here:
////////////////////////////////////////////////////////////////////// My Project Title// A description of this file goes here.// // Copyright (C) 2006 My Company////////////////////////////////////////////////////////////////////
One easy way to do this is to define a header template called java.header, which would contain the above text, and then to indicate which lines may be modified:
Suppose that all you need to do is to put a copyright line at the top of each file:// Copyright (C) 2006 MyCompany// All rights reserved
However, the year needs to change each year. To do this, you can define an inline regular expression using the RegexpHeader module, as shown here:
You can also define the header as a more complicated regular expression in an external file. Suppose your company or project standards require a file header containing dynamic elements coming from the source configuration system, as in the following example:
////////////////////////////////////////////////////////////////////// My Project Title// File: $Id$// A short description goes here//// Last modified $Date$ by $Author $// Copyright (C) 2006 My Company////////////////////////////////////////////////////////////////////
This can be configured using the RegexpHeader module and an external file template (called "java.header" in this example):
The java.header file in this case would look like this:
^////////////////////////////////////////////////////////////////////^// My Project Title^// File: $Id.*$$^//.*$^//^// Last modified $Date.*$ by $Author.*$$^// Copyright (C) dddd My Company^////////////////////////////////////////////////////////////////////
There are many other modules that can be activated and configured. Check out the Checkstyle documentation for further details.
Suppressing Checkstyle Tests
There will be times when you come across a genuine reason for violating a coding standard for a particular section of code. For example, the following code extracts the list of students in each percentile:
for (int i = 1; i < 100; i++) { List students = extractCentile(i, examResults); ?. }
In this context, the use of the value 100, for example, is clear, and there is little added value in replacing it by a constant called ONE_HUNDRED. Checkstyle lets you get around this problem in several ways. The easiest way to deal with particular cases like this is to use the SupressionCommentFilter module. This module lets you deactivate Checkstyle for a section of code:
// CHECKSTYLE:OFF ? 100 is not a "magic number" in this case for (int i = 1; i < 100; i++) { // CHECKSTYLE:ON List students = extractCentile(i, examResults); ?. }
Another way to do this is to use the SuppressionFilter, associated with an XML configuration file, where detailed suppressions can be specified. This approach is useful for deactivating rules for large blocks of code or across several classes.
The code above calls a suppressions.xml file, a file that you need to write where you can deactivate particular checks for particular classes, or even for certain lines in a particular class. In the following example, all Javadoc checks are deactivated for the first 50 lines of the Catalog class, and the MagicNumberCheck is deactivated for all unit test classes.
This approach does require extra maintenance work to keep the suppression.xml file up to date. Developers may also be tempted to use wildcards a little excessively, which can reduce the efficiency of CheckStyle audits. In practice, this method should be used sparingly and only after other options have been considered and eliminated.
Integrating Checkstyle into the Build Process
Once you have defined and agreed upon a coding standard, it needs to be integrated into the daily routine. Integrating a Checkstyle plug-in into the IDE on each developer machine is a good start. However, coding standards really need to be enforced and verified systematically across the whole project. The nightly project build is often a good place to do this.
Checkstyle is delivered with an Ant task, which can be used to generate a report in HTML form. Maven integrates Checkstyle reports "out-of-the-box," via the Maven Checkstyle Plugin (see Figure 6). Whatever build tool you are using, Checkstyle audits should be run on the entire project at least once daily, and the results published on the project Web site.
![]() | |
Figure 6. Reporting: The screen shot shows a Checkstyle report generated by Maven. |
It is a good idea to put your project Checkstyle configuration file under source control in the project, and refer to the same file from both the developer work environments and the build tool. This helps to ensure that the same standards will be applied on developer machines and in the build process.
Adopting Coding Standards
Like so many other things in software project management, a good dose of people skills will help you succeed in a new coding standards implementation.
The high priority of the project needs to be clear from the outset. Management (both the project manager and high-level management) must make sure developers understand that code standards are important or they'll never be enforced. It is one thing to automatically generate (and even publish) code audits, it is another to make them part of developer daily routine. Individual mentoring and coaching can be useful here. Another approach is to review code audit results in project meetings. Whatever techniques are used, the key is to get and maintain developer buy-in.
Coding Standards and Code Reviews
It is important to note that automatic source code audits do not by any means replace code reviews. When well used, code reviews can be a powerful tool for software quality improvement. Code reviews are an essentially human activity, as they rely heavily on human judgment to be efficient.
However, Checkstyle reports can make code reviews easier and faster by automating the numerous fastidious checks that make up a set of coding standards. This lets code reviewers concentrate on more high-level issues, and also saves time by ensuring that the code is clear and easily readable.
Coding standards will cost you some time at the outset, while developers get used to the new way of working. This is where developer and management buy-in is important. If developers feel that coding standards have strong support from project and company management, they should quickly become a normal part of developer work. Once developers have fully adopted the coding standards, the costs of applying them will be minimized and benefits will become apparent.