Chris has posted 1 posts at DZone. View Full User Profile

JSR 305 and Design by Contract

06.24.2008
| 6345 views |
  • submit to reddit
Static Analysis tools have become common place among many Java projects. Their practicality is unquestionable, and if you aren’t currently making use of them within your projects you definitely should take a look at doing so.

The purpose of this post however is not to dictate to my readers how they should be running their software projects, it is more intended to give a brief overview of a newly proposed Java Specification Request. JSR 305’s purpose is to offer a set of annotations to the Java Developer in order to make Static Analysis tools smarter.

As an aside, if you haven’t heard of Static Analysis tools like FindBugs, or even JSR305 and are interested in learning more about it before reading this post I suggest you checkout William Pugh’s (Creator of FindBugs) Google Tech Talk on JSR 305. This presentation will help clarify what this JSR is trying to accomplish and may familiarize you more with what Static Analysis tools are trying to accomplish.

Continuing, why do Static Analysis tools need help in anyway? Aren’t these tools supposed to be sophisticated enough to determine what is and isn’t a bug? Although these tools are quite powerful they are far from perfect and commonly call question to code that is perfectly correct. This JSR is an attempt to help solve those issues and it is my feeling that this JSR will also help introduce the ability for developers to define contracts for their implementers to follow.

Many languages, like Eiffel, are built on top of the theory of Design by Contract. Design by Contract is an approach to designing software that allows developers to strictly define a set of invariants and specifications for classes and objects. If you interested in this topic I will refer you to Bertrand Meyer’s (the man behind Design by Contract and the Eiffel Programming Language) amazing book Object-Oriented Software Construction.

It is my opinion that any project can benefit from adapting some or all the ideas from Design by Contract and it does not necessarily require a lot of work to do.

Now that I have digressed from my original point, let’s take a brief look at what JSR305 brings in terms of annotations. I’m assuming that you are already familiar with JSR305 and annotations in Java.

The current proposal, remember this is still a work in progress, includes annotations for Nullness, Sign, Return type & Purity, Taint, Language, and Threading. Each of these annotations should help the developer clearly define valid states for methods and variables in their classes so that tools like FindBugs can spot violations with certainty.

These annotations also work to bring automatic software documentation directly from Design by Contract, as they help the developer clearly define a set of valid states that implementers can refer to when using their code. In theory these annotations could also be used by IDE’s in order to warn developer and implementers if they are violating any of these states.

Let’s look at a piece of Eiffel code as an example of how Design by Contract actually works, and how JSR305 will help achieve something similar in Java. The following example is a simple counter class that allows you to increment, decrement, and reset a counter. The counter class however has a set of valid states for which it must maintain.

First the counter must never be less then zero. This is important as an implementer could create an instance of this class and call the decrement function leading to odd behaviours. Second the increment and decrement must change the state of the counter in some way either by decrementing it or incrementing it. The decrement function also has a third requirement that the counter not be zero before calling this function.
indexing
description: "Counters that you can increment by one, decrement, and reseet"
class interface
COUNTER
feature -- Access
item: INTEGER --Counter's value
feature -- Element change
increment is
-- Increase counter by one
ensure
count_increased: item = old item + 1
decrement is
-- Decrease counter by one.
require
count_not_zero: item > 0
ensure
count_decreased: item = old item - 1
reset is
-- Reset counter to zero.
ensure
counter_is_zero: item = 0
invariant
positive_count: item >= 0
end

Even if you are not familiar with Eiffel programming, just by looking at the invariants you could easily tell what this class does, and exactly how to use it, a beautiful property of Automatic Software Documentation.

Now compare this to a similar Java class, which offers the same functionality but minus the contract between the developer and implementer.

/**
* A Simple Example of a counter.
*
* @author Chris Boersma
*/
public class Counter {

private Integer item;

public void Counter() {}

public void create() {

item = new Integer(0);
}

public void increment() {

item++;
}

public void decrement() {

item--;
}

public void reset() {

item= new Integer(0);
}
}

You can quickly see that you loose sense of what is a valid state for this class, and exactly you are guaranteed of in terms of functionality.

Now put yourself in the seat of a static analysis tool. What is a bug here? Are there any bugs? In reality there probably aren’t. It is quite possible that this class functions exactly as it was intended, perhaps the developer wanted a Counter that could be decremented to a value less then zero. It is extremely difficult to determine without a doubt that this code is “bug” free, and this is just a simple counter, imagine having to determine whether a complex class of over 500 lines of code is indeed “bug” free.

Now take that 500 lined class, and integrate it with other components of a system and you quickly realize how difficult a task static analysis tools actually have, and why JSR305 is really quite important.

I could now quickly delve into an example illustrating how JSR305 will make this code 100% fools proof, but I don’t really see a point in doing so. Right now the JSR hasn’t even clearly defined what set of annotations it will support so anything I type here could quickly become obsolete and irrelevant.

My purpose here is merely to exercise your mind, and show you that Static Analysis tools like FindBugs combined with JSR305 could bring a whole new world of programming to the Java community. I mean how many of us would argue that writing cleaner, safer code is really all that bad?

At this point I could delve into the different views regarding these new annotations, but I’ll save that for another discussion as this JSR develops into something more concrete. I personally think it’s far to early to pick sides, and I personally feel that there valid points being made as to whether this JSR makes sense or whether it is completely useless to the Java community.

I suggest everyone keep their eye on this JSR and if you feel strongly about something open up a discussion over at the JSR’s google groups page http://groups.google.com/group/jsr-305/ It’s better to have your voice heard and introduce some meaningful discussion with the JSR creators then to sit on the fence (or your blog) and call foul.

From http://www.kungfuice.com/

Published at DZone with permission of its author, Chris Boersma.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Michael Schnell replied on Tue, 2008/06/24 - 8:03am

There are already two good DBC implementations:

Contract4J

SpringContracts

Yanic Inghelbrecht replied on Wed, 2008/06/25 - 4:43am

A very sloppy post if you ask me.

The issue of DBC has come up several times on the JSR-305 list and right from the start the expert group decided NOT to support DBC. Last time I looked (2 months ago), their viewpoint hadn't changed. Are you saying they've changed their minds?

Design by contract does not lend itself to static analysis in general. Only simpler cases (using theorem provers) or specific kinds of assertions (like non-nullness) may be statically analyzed. In practice, it has always been a dynamic verification technique.

Also, it is NOT an 'automatic' documentation technique. Anyone who's used it for more than the textbook Stack and Counter classes will tell you that you have to work pretty hard to come up with a decent spec. That's what it is : a specification technique.

Neither Contract4J nor SpringContracts are ready for prime time. Even Eiffel's DBC has been shown to be less than ideal because of the way contract clauses are combined in inheritance hierarchies and its vague invariant semantics. AFAIK, despite some interesting research results in the last 20 years, it has never been updated. Most current attempts at DBC blindly follow the plan Bertand Meyer laid out, which is a pity.

Anyway, if you want something decent for Java that is ready for use NOW, have a look at the Java Modeling language (JML).


> I could now quickly delve into an example illustrating how JSR305 will make this code 100% fools proof, but I don’t really see a point in doing so.

Now that would've been more interesting. Please do, I'm curious.

Brent Hanson replied on Sat, 2009/04/04 - 9:37pm

Some additional interesting thoughts on JSR 305.

http://kloctalk.klocwork.com/?p=133

 

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.