Tools for Java Coding Standards... now we can all get along!
By Mark Volkmann, OCI Partner
November 2002
Introduction
Ever tried to get a group of software developers to agree on a coding standard?
We're all reasonable people, right? Certainly we're mature enough to come to an agreement on decisions that are based on personal preference.
Well, after 20 years of working in the software business, I've never seen a team of developers successfully do this. Sure, some dissenting team members can be beaten down until they conform, but they're not happy about it.
How do we get past personal biases about coding standards and move on to getting work done?
The answer, in my opinion, is to let everyone do what they want!
I can hear objections being raised as I write this. We'll have too much trouble reading code if we all do it differently. The end product will be inconsistent ... and so on.
We need to make a clear distinction between standards related to style and standards related to best practices.
Examples of style standards are where to place braces and how to use whitespace. Examples of best practices are when to use interfaces and how to implement an equals method.
When I say "let everyone do what they want," I'm referring only to style standards.
So how can we let everyone use whatever style they prefer and not suffer for it?
Answer: Use a tool like Jalopy, an open source tool available at SourceForge, to reformat code to a single style.
When developers get code from the source repository, they can use Jalopy to reformat it to their preferred style. Before they commit changes to the source repository, they can run Jalopy again to reformat the code to a style selected for the project.
It's a good idea to find a way to hook Jalopy into the check-in/commit functionality of the repository so that developers can't bypass this step. Putting the code back in a common format is essential so that reasonable diffs can be performed to determine the changes made between revisions of the code.
What about those non-style, best practice issues?
That's were CheckStyle comes in. It's another open-source tool available at SourceForge.
Both tools can be run from the command-line or an Ant build file, or they can be integrated with an IDE.
This article only discusses the first two options, since there are too many variations in IDE setup to cover in a single article. See the documentation of each tool for instructions on how to integrate them with a particular IDE.
Jalopy
Jalopy is an open-source tool for reformatting Java source code released under a BSD licence.
Jalopy can control:
- Brace placement
- Whitespace usage
- Indentation
- Line wrapping
- Code order
Jalopy can also insert Javadoc and header/footer templates.
Jalopy has plugins for running in many different environments. You can download either a version containing the source code plus every plugin or a version containing a single, specific plugin.
Jalopy can be run from the command line (using the console plugin), an Ant build file, or an IDE. It has been successfully integrated with these IDES:
- Eclipse 2.0
- JBuilder 5.0 or above
- JDeveloper 9i (Oracle)
- jEdit 4.1pre1 or above
- NetBeans 3.3 or above
- Sun ONE Studio 4 (based on NetBeans)
Some IDEs, such as IDEA, have such good support for code formatting that there would be little interest in creating a Jalopy plug-in.
Downloading and Installing Jalopy
Jalopy can be downloaded from http://jalopy.sourceforge.net. Installation is easy; simply unzip and add its bin directory to the PATH environment variable.
Configuring Jalopy
Running the preferences script (either .bat
or .sh
) in the bin directory opens a Swing GUI where coding style preferences can be specified.
In addition, a preview window is displayed to show the effect of your choices.
Selecting a category in the left navigation area changes the content of the main area of the GUI to allow preferences for that category to be specified. It also changes what is displayed in the preview window.
Multiple sets of preferences, called "projects," can be created. Preferences for each project are saved in separate, binary files. This makes using the GUI the only practical way to view and modify preferences.
In Windows XP, the preference files are stored under C:\Documents and Settings\user-name\.jalopy.
A default project is created the first time the GUI is used. Click on the "Projects" category to view the current list of projects (see Figure 3).
The active project will appear in bold. This is the project that will be affected by changes made under the "Printer" category (see Figure 1). It is also the project whose preferences will be used when Jalopy is run.
To change the active project, select a non-bold project name and click the "Activate" button. To create a new project, click the "Add..." button. Remember to activate it if you want to specify preferences for it and use it!
Running Jalopy from the Command Line
To run Jalopy from the command-line, add bin\jalopy-console-version.jar
to your CLASSPATH and enter commands with the following format.
Note: When running under Linux, it may be necessary to change the.sh
script files to UNIX format and addgetopt-version.jar
to your CLASSPATH.)
jalopy [options] args
Common usages are described below.
To run on a single source file and overwrite it:
jalopy classname.java
To run on a single source file and avoid overwriting it, redirect output to a different file:
jalopy classname.java > classname.new
To run on all source files below the current directory and overwrite them:
jalopy -r .
To run on all source files below the current directory and avoid overwriting them:
jalopy -r . -d output-directory
To get help on all the available options:
jalopy -h
Running Jalopy from Ant
To enable Ant to find the Jalopy JAR files, either copy them to the Ant lib
directory or insert the following taskdef
into your Ant build file.
- <taskdef name="jalopy"
- classname="de.hunsicker.jalopy.plugin.ant.AntPlugin">
- <classpath>
- <fileset dir="jalopy-dir/bin">
- <include name="*.jar"></include>
- </fileset>
- </classpath>
- </taskdef>
Here's an example Ant target for running Jalopy on all Java source files in a project.
- <target name="format" depends="compile"
- description="reformats all Java source files in the project">
- <taskdef name="jalopy" classname="de.hunsicker.jalopy.plugin.ant.AntPlugin"></taskdef>
- <jalopy classpathref="classpath">
- <fileset dir="${src.dir}">
- <include name="**/*.java"></include>
- </fileset>
- </jalopy>
- </target>
The taskdef
in the example above is only needed if the previous one is not used. As written, it expects the Jalopy JAR files to be in the Ant lib
directory.
This target depends on the compile
target because formatting code that contains syntax errors may produce undesirable results. classpath
is the id of a path
element that is also used to compile the source code. Depending on compile
and specifying the classpath
are only necessary to take advantage of import optimization.
Import optimization has three possible settings:
- Disabled
- Expand
- Collapse
When set to expand, all wildcard imports are replaced by explicit imports. When set to collapse, multiple explicit imports for the same package are replaced by a single wildcard import for the package.
For details on other attributes that can be specified on the Jalopy task see docs\plugin-ant-usage.html.
CheckStyle
CheckStyle is an open-source tool for checking conformance of Java source code against a set of coding standards that are highly configurable. It is released under a GNU Lesser General Public Licence (LGPL).
Here are highlights of what CheckStyle can check.
- javadoc comments
- reports classes, interfaces, fields, and methods that don't have a javadoc comment
- can specify the minimum visibility scope that requires them (for example, protected)
- default scope is private, which requires javadoc on everything
- naming conventions
- reports names that don't conform to specified conventions
- checks names of every package, class, interface, constant, static field, instance field, method, parameter, and local variable
- headers
- reports source files that don't begin with a specified header, which is typically used to provide copyright information
- imports
- reports imports that aren't needed
- reports imports with restricted package prefixes (defaults to sun)
- size violations
- reports lines that are too long (default limit is 80 characters)
- reports methods with too many lines of code (default limit is 150)
- reports constructors with too many lines of code (default limit is 150)
- reports source files with too many lines of code (default limit is 2,000)
- reports methods and constructors that take too many parameters (default limit is 7)
- reports casts and commas not followed by a space
- reports periods preceded or followed by a space
- reports incorrect spacing around parentheses
- reports incorrect line wrapping of expressions containing operators
- whitespace
- reports files that contain tab characters
- reports keywords not surrounded by spaces (
if
,for
,while
,do
,catch
,synchronized
, andreturn
)
- modifiers
- reports wrong order of modifiers
(public
,protected
,private
,abstract
,static
,final
,transient
,volatile
,synchronized
,native
, andstrictfp
) - reports use of unnecessary public and abstract modifiers in interfaces
- reports non-private fields
- reports wrong order of modifiers
- blocks
- reports missing braces
- reports empty blocks (can require that they at least contain a comment)
- reports non-conforming placement of left and right braces
- and more
- reports comments containing "TODO:"
Downloading and Installing CheckStyle
CheckStyle can be downloaded from http://checkstyle.sourceforge.net. Installation is easy; just unzip and add checkstyle-all-version.jar
to the CLASSPATH environment variable.
Configuring CheckStyle
To override the coding standards checked by CheckStyle, create a Java property file describing alternate settings.
An example of a CheckStyle property is "checkstyle.maxlinelen" which defaults to 80. For details on specific properties that can be set, see docs\config.html.
The property file to be used can be specified in a command-line option or in the properties
attribute of the checkstyle
Ant task.
Running CheckStyle from the Command Line
To run CheckStyle from the command line, enter commands with one of the following formats. The difference between them is that the first requires the CLASSPATH environment variable to be set and the second doesn't.
java com.puppycrawl.tools.checkstyle.Main [options] [source-files]
or
java -jar %CHECKSTYLE_HOME%\checkstyle-all-2.4.jar [options] [source-files]
Options include:
-f xml
to specify that XML output should be generated instead of plain text, which is the default. Thecontrib
directory contains XSLT stylesheets that can be used to transform the XML output into HTML.-p property-file
to specify a property file which configures the checks that will be performed-o file
to specify the name of the output file. If this option isn't used, output is written tostdout
.-r directory
to specify the directory containing the Java source files to be checked. All .java files in and below that directory will be checked.
Running CheckStyle from Ant
To enable Ant to find the CheckStyle JAR file, either copy it to the Ant lib
directory or insert the following taskdef
into your Ant build file.
- <taskdef name="checkstyle"
- classname="com.puppycrawl.tools.checkstyle.Main"
- classpath="checkstyle-dir/checkstyle-all-2.4.jar.jar"></taskdef>
Here's an example Ant target that runs CheckStyle on all Java source files in a project and produces an HTML report.
<target name="check"
description="checks all Java source files for coding standard violations">
<taskdef name="checkstyle" classname="com.puppycrawl.tools.checkstyle.CheckStyleTask"></taskdef>
<checkstyle properties="checkstyle.properties"
failOnViolation="false" failureProperty="check.failed">
<fileset dir="${src.dir}" includes="**/*.java"></fileset>
<formatter type="xml" toFile="checkstyle.xml"></formatter>
</checkstyle>
<xslt in="checkstyle.xml" out="checkstyle.html"
style="checkstyle-dir/contrib/checkstyle-noframes.xsl"></xslt>
</target>
The taskdef
in the example above is only needed if the previous one is not used. As written, it expects the Checkstyle JAR file to be in the Ant lib
directory.
Setting failOnViolation
to false
causes it to continue checking source files after one has failed to pass all the checks.
failureProperty
specifies an Ant property to set if one or more checks fail. This can be used in subsequent Ant targets to prevent them from running.
Software Engineering Tech Trends (SETT) is a regular publication featuring emerging trends in software engineering.