打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Automated code reviews with Checkstyle, Part 2 | JavaWorld

Checkstyle makes it easy to automate code reviews once the code has been committed, but wouldn't it be better if programming errors never made it that far? In this second half of "Automated code reviews with Checkstyle," authors ShriKant Vashishtha and Abhishek Gupta show you how to be proactive about code quality. Find out how to use Checkstyle's custom rules to enforce code standards and catch mistakes -- long before code is committed to your code base. Level: Intermediate


Enjoy premium bluetooth wireless Music and a lifetime warranty against sweat, at a significantly

Read Now

In the first half of this article, you learned how easy it is to create and use custom Checkstyle rules for automated code reviews. The solution we presented in that article was only partial, however: it offers custom rules but no mechanism for keeping faulty code out of your code base. In this article we'll show you how to use Checkstyle to proactively enforce code standards, first by catching them as they're written, and then by catching them at the source repository level. Proactively enforcing code standards at these levels will make code reviews less time-consuming, and will allow your team to concentrate on the finer points of code quality.

The first example is based on a custom Eclipse plugin, which displays a warning when it spots a problematic line of code. The second example, especially good for teams not using Eclipse, shows you how to use Subversion's pre-commit hook to check for code violations. This approach bars developers from committing source code with un-fixed violations.

We'll start with building the custom Eclipse plugin to handle custom checks. If you're not familiar with creating custom rules in Checkstyle, you should probably read the first half of this article before continuing. If you're not using the Eclipse IDE, skip ahead to learn about enforcing code standards with Subversion's pre-commit hook.

Build an Eclipse plugin to enforce custom rules

The standard eclipse-cs Eclipse plugin works well for Checkstyle's built-in checks, but you'll need to create your own plugin to handle custom checks. For the sake of demonstration, we'll use IllegalExceptionThrowsCheck, the simpler custom check from the first half of this article. The sample code for this article contains the source code for IllegalExceptionThrowsCheck. Note that we assume familiarity with the Eclipse development environment and plugins.

Before you begin, you have the option to provide metadata in the form of a checkstyle-metadata.xml file for the custom checks; this makes it easier to use the capabilities of the Eclipse plugin's configuration editor. Place this file into the packages where your check classes reside. You'll be able to configure your custom check with the editor just as you can any standard Checkstyle module. Listing 1 contains the sample configuration for your custom check, IllegalExceptionThrowsCheck.

Listing 1. Changes in plugin.xml for custom checks

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE checkstyle-metadata PUBLIC"-//eclipse-cs//DTD Check Metadata 1.0//EN""http://eclipse-cs.sourceforge.net/dtds/checkstyle-metadata_1_0.dtd"><checkstyle-metadata>  <rule-group-metadata    name="Custom Checks"      priority="900">      <rule-metadata name="Illegal Exception Throw"        internal-name="IllegalExceptionThrowsCheck"        parent="TreeWalker">          <alternative-name            internal-name="com.abc.checkstyle.check. IllegalExceptionThrowsCheck" />          <description></description>          <property-metadata name="illegalExceptionsInThrows"             datatype="String"            default-value="Exception,java.lang.Exception">            <description></description>          </property-metadata>      </rule-metadata>  </rule-group-metadata></checkstyle-metadata>

The root <checkstyle-metadata> tag can contain the metadata of multiple rule groups, each with a <rule-group-metadata> tag. The name attribute is used as the display name, and the priority attribute influences the order in which the groups appear in the configuration editor.

The rule-metadata elements contain the metadata information for a check module. internal-name is the logical name of the module, and parent determines whether the module is a FileSet check or a regular TreeWalker check.

Every rule-metadata element must contain at least one alternative-name element that provides the mapping of this check with the one available in the Checkstyle configuration file created for custom checks. (That is, custom_check.xml, in this case the name could be something else.) This file is used to configure the custom Checkstyle checks and is placed in the <path-to-my-eclipse>/plug-ins/com.atlassw.tools.eclipse.checkstyle_x.x.x directory. The rule-metadata element may also contain property-metadata elements, which are used to configure the check in the plugin configuration editor.

Next, you need to package the already created custom checks into a JAR file and place that file in the <path-to-my-eclipse>/plug-ins/com.atlassw.tools.eclipse.checkstyle_x.x.x/extension-libraries directory. Then copy custom_check.xml to the Checkstyle plugin folder. After that, you'll need to make some changes in plugin.xml, which is located in the Checkstyle plugin folder (<path-to-my-eclipse>/plug-ins/com.atlassw.tools.eclipse.checkstyle_x.x.x). You'll put the details of your extensions under the <extension> tag, as shown in Listing 2.

Listing 2. Changes in plugin.xml

<!--     Standard plugin check configurations    -->   <extension id="checkstyle.CheckConfiguration"     point="com.atlassw.tools.eclipse.checkstyle.configurations">       <check-configuration          name="Sun Checks"          location="sun_checks.xml"          description="%SunChecks.description"/>       <check-configuration          name="Custom Checks"          location="custom_check.xml"         description="%CustomChecks.description"/>       <check-configuration          name="Sun Checks (Eclipse)"          location="sun_checks_eclipse.xml"          description="%SunChecksEclipse.description"/>   </extension>

As the description attribute of the check-configuration tag can be internationalized, it is externalized in <path-to-my-eclipse>/plug-ins/com.atlassw.tools.eclipse.checkstyle_x.x.x/plugin.properties, as shown in Listing 3.

Listing 3. Changes in plugin.properties

CustomChecks.description = Checkstyle configuration that checks the project specific coding conventions.

You will be able to see this configured description under the Description tab of the Checkstyle space in the Eclipse configuration, as illustrated in Figure 1.

Figure 1. Checkstyle plugin configuration (click to enlarge)

Next, you need to restart Eclipse at the command prompt with the -clean option, as follows:

<path-to-eclipse> eclipse -clean

Now, in Eclipse choose Windows > Preferences > Checkstyle. You'll see your custom checks in the editor, as illustrated in Figure 2. You can set this new set of checks as the default for an entire workspace, or can choose a subset of them for a specific project.

Figure 2. Project-level Checkstyle configuration (click to enlarge)

After you have configured your Eclipse project with the custom Checkstyle checks, code that violates the rules laid down in your Checkstyle configuration will cause an an error, along with message describing the problem. For example, if you configured a project with a rule limiting the number of methods that a class could have, going over that limit would result in a message like the one shown in Figure 3.

Figure 3. Applying custom Checkstyle rules in Java source code (click to enlarge)

Subversion pre-commit hooks

What if your project uses an IDE other than Eclipse? Or, even if your team does use Eclipse, what if one of your developers uses some other text editor to create Java classes and commit them into Subversion? It's very difficult to track these kinds of issues unless you're using a continuous integration environment for continuous builds.

One solution is to apply Checkstyle rules at the repository level, using Subversion. This approach bypasses the IDE and prevents developers who don't comply with project-level coding standards from committing source code to the SCM repository. If you want to be extra proactive, you can combine this approach with compile-time build checks via the Eclipse plugin or at Ant-based build time. By default your build tool will be able to tell you if your source code has passed the checks or not. Even developers who escape build-time checks will be caught when they attempt to commit the non-compliant code into Subversion. All of this is possible using SVN's repository hooks.

What are repository hooks?

A hook is a program triggered by some repository event, such as the creation of a new revision or the modification of an unversioned property. Some hooks (so-called pre hooks) run in advance of a repository operation and provide a means by which to both report what is about to happen and to prevent it from happening at all. Other hooks (called post hooks) run after the completion of a repository event and are useful for performing tasks that examine -- but don't modify -- the repository. Each hook is given enough information to tell what an event is (or was), the specific repository changes proposed (or completed), and the username of the person who triggered the event.

The Subversion hooks subdirectory is, by default, filled with templates for various repository hooks, as you can see in Listing 4.

Listing 4. Default repository hooks

$ cd /home/shrikant/svn/myrepos/hooks$ lspost-commit.tmpl post-unlock.tmpl pre-revprop-change.tmplpost-lock.tmpl pre-commit.tmpl pre-unlock.tmplpost-revprop-change.tmpl pre-lock.tmpl start-commit.tmpl$

These are they types of hooks you can find in a Subversion repository:

  • start-commit: Notification of the beginning of a commit.
  • pre-commit: Notification just prior to commit completion.
  • post-commit: Notification of a successful commit.
  • pre-revprop-change: Notification of a revision property change attempt.
  • post-revprop-change: Notification of a successful revision property change.
  • pre-lock: Notification of a path lock attempt.
  • post-lock: Notification of a successful path lock.
  • pre-unlock: Notification of a path unlock attempt.
  • post-unlock: Notification of a successful path unlock.

As previously noted, the interesting hook for the purposes of this article is the pre-commit hook. This hook is run just before a commit transaction is promoted to a new revision. Typically, this hook is used to protect against commits that are disallowed due to content or location -- for example, the incoming log message should be non-empty, and the hook will prevent the commit if that's not the case.

If the pre-commit hook program returns a non-zero exit value, the commit is aborted, the commit transaction is removed, and anything printed to stderr is marshaled back to the client.

Implementation

It should be obvious at this point that a pre-commit hook can be used to check Java files against Checkstyle rules before those files are committed in Subversion. Pre-commit hooks are either shell scripts (on UNIX-like systems) or .bat/.exe files (on Windows systems). As soon as a new Subversion commit is processed, the Subversion kernel calls any repository hooks available. So, if a pre-commit hook could somehow call a Checkstyle command for each Subversion transaction (list of files) being committed, it would return a list of errors. For checking errors for a Java file, the Checkstyle command is as follows:

java -classpath checkstyle-customchecks.jar:checkstyle-all-<version>.jar com.puppycrawl.tools.checkstyle.Main -c <JavaFileName>

If a repository pre-commit hook could intercept files about to be committed, execute that command, format the errors, and display them to the developer, you'd be sitting pretty. Building something like that from scratch would take time and require knowledge of Subversion internals. Fortunately, some good open source projects are focused on the usage of Subversion hooks. One of them is Subversionchecker, a project based on Python. Subversionchecker is quite modular and provides you with sets of checks (Checkstyle, UnitTests, XMLValidator, AccessRights, Checkout, etc.) and handlers. For each kind of check, you can also configure what you want to do (send the message to console, for example, or to a file, or through e-mail); that comes under the handler's module.

For the purposes of this article, you'll use Checkstyle to check only the pre-commit hook of a repository. As you might have already guessed, Subversionchecker provides a configuration file to let you choose among checks and handlers. In the rest of this section, you'll configure Subversionchecker for your Subversion repository and custom Checkstyle check. Please note that all of these steps should be executed on your Subversion server machine.

To begin with, you'll need to download and install Python so that it's available for your pre-commit hook script. Download and install Subversionchecker as well.

Next, you need to check to see if a pre-commit hook script is already available in your Subversion repository in the hooks directory. If not, you may want to copy the existing pre-commit.tmpl file (which is located in that same hooks directory) to the pre-commit file. You'll want to make changes to the file as follows:



<Subversionchecker_installed_path>/Subversionchecker-<version>/Main.py PreCommit $REPOS $TXN || exit 1

To configure Subversionchecker, you need to provide information in a configuration file, called Subversioncheckerconfig.ini, which is located in the hooks directory of the Subversion repository. Listing 5 shows the configuration required for your Checkstyle check.

Listing 5. Configuring Subversionchecker to work with your Checkstyle check

+1 [Default]   +2 ; This property tells Subversionchecker about all checks (UnitTests, AccessRights, XMLValidator etc) it should execute. Separated with comma (",")  +2 Main.PreCommitChecks=Checkstyle    +4 ; Path of java executable to run Checkstyle command  +3 Checkstyle.Java=/usr/bin/java   +6 ; Classpath for executing Checkstyle rules  +4 Checkstyle.Classpath= /home/shrikant/checkstyle/custom_checks.jar:/home/shrikant/checkstyle/checkstyle-all-4.3.jar   +8 ; Configuration file for Checkstyle to run its rules.  +5 Checkstyle.ConfigFile= /home/shrikant/checkstyle/custom_checks.xml   +9 ; In case of failures, where should Subversionchecker redirect the errors +10 Checkstyle.FailureHandlers=Console

Note that in .ini files ; denotes a comment. The meaning of each property should be fairly obvious. All of the properties in Listing 5 are mandatory for running Checkstyle with Subversionchecker.

As you can see, with Subversionchecker you can configure any kind of Checkstyle rules. Now, when you try to commit Java files with errors into Subversion, you'll get errors from Checkstyle of the kind shown in Listing 6.

Listing 6. Errors thrown during a failed Subversion commit

~/svn/myrepo/SampleProject/src/com/sample$ svn commit -m "Sample" Sending        sample/Test4.java Transmitting file data .svn: Commit failed (details follow): svn: MERGE request failed on '/svn/myrepo/SampleProject/src/com/sample' svn: 'pre-commit' hook failed with error output:  ================================================================================ Coding style errors found:  Starting audit... /tmp/tmpudEfyg/SampleProject/src/com/sample/Test4.java:2: too many methods, only 3 are allowed /tmp/tmpudEfyg/SampleProject/src/com/sample/Test4.java:18:35: Method call not allowed in Conditional Expr -> getLength Audit done.  See Checkstyle documentation for a detailed description: http://checkstyle.sourceforge.net/ ================================================================================

Enjoy premium bluetooth wireless Music and a lifetime warranty against sweat, at a significantly

READ NOW

Conclusion to Part 2

This two-part article has introduced you to building custom rules for automated code reviews, and then using them to proactively enforce code standards before code enters your code base. As we demonstrated in the first half of this article, creating custom rules for Checkstyle is actually easy to do. Once you have a set of custom rules, or checks, you can use them to enforce project-specific coding standards in automated code reviews. We showed you how to create both a simple rule and a more complex one; both examples can be found in the article source code.

In the second half of the article, we took the notion of proactive code reviews to the next level, showing you how to catch faulty code before it enters your code base. Creating a custom Eclipse plugin enables you to alert developers on your team when they violate custom rules (assuming they're using Eclipse). We also showed you how to use and configure SVN's pre-commit hook, which prevents developers from committing rule-breaking code to the project repository. Either way, the end result is cleaner code with less hassle for you. See the Resources section below to learn more about Checkstyle and other tools for monitoring, reviewing, and enforcing code quality.

ShriKant Vashishtha is a principal consultant at Xebia, specializing in agile offshore software development and consulting. He has more than ten years of experience in the IT industry and is involved in designing technical architectures for various large-scale Java EE projects, applying Agile methodologies like Scrum and Agile-RUP. ShriKant holds a bachelor's degree in engineering from the Motilal Nehru National Institute of Technology in Allahabad, India.

Abhishek Gupta currently works as a technical lead for Tata Consultancy Services in India. He has more than four years of experience in the IT industry and is involved in designing technical architectures for various large-scale Java EE and Java ME projects for the transport, banking, and retail industries. Abhishek holds a bachelor's degree in engineering from Uttar Pradesh Technical University in Lucknow, India.

Learn more about this topic

Product information and downloads

Automated code reviews on JW

Build tools and integration management on JW

JW recommends

  • Light Heat Code: Effective code reviews: Presents a stripped down code review process for a small, agile shop.
  • In pursuit of code quality (Andrew Glover, IBM developerWorks): A column series introducing tools and techniques for establishing and maintaining code quality.
  • Java Power Tools (John Ferguson Smart; O'Reilly Media, April 2008): A must-have reference guide to open source tools for Java developers. Hear this: Author John Smart discusses the tools he uses and why.

More from JavaWorld

  • Visit the JavaWorld SDLC research center for more articles about tools and techniques for managing the Software Development Life Cycle.
  • JavaWorld's community platform is growing: Check out JW Blogs and the improved Java Q&A Forums.
  • Also see Network World's IT Buyer's Guides: Side-by-side comparison of hundreds of products in over 70 categories.
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Using Eclipse PDT for Drupal Development | Co...
Nuxeo Blogs: Open Source ECM now? Think CPS!
CMake:Eclipse UNIX Tutorial
Summer of Code Scala Projects
Perl IDE and Programming Environment
Continuous Integration
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服