Contracts for Java
Posted:
Friday, February 4, 2011
If you’ve ever spent hours debugging your Java code, today’s blog post is for you.
Often bugs that are frustratingly elusive and hard to track down appear simple or even trivial once you have found their cause (the fault). Why are those bugs hard to track down? One possibility is that the fault is in a completely different part of the program than its symptom (the failure).

Contracted code reveals failures much closer to their fault, leaving you with a far simpler problem to solve:
Traditionally, Java programmers enforced preconditions using explicit parameter validation code in public methods, and assertions in non-public methods. Likewise, they enforced invariants and postconditions using assertions. This approach is described in detail here. Since then, new features in Java 5 have enabled a more convenient and expressive implementation of contracts.
Contracts for Java is our new open source tool. Preconditions, postconditions, and invariants are added as Java boolean expressions inside annotations. By default these do nothing, but enabled via a JVM argument, they’re checked at runtime.
Contracts help you turn interface documentation into code. For example:
Could be expressed as:
The interface is now precise and every class that implements it can be checked at runtime.
Contracts are a powerful language feature and can provide great benefit if used correctly. We recommend that newcomers find an expert to learn from or spend some time reading around the subject to pick up good habits and avoid bad ones.
One point that often surprises people is that contracts must not be used to validate data. Contracts exist to check for programmer error, not for user error or environment failures. Any difference between execution with and without runtime contract checking (apart from performance) is by definition a bug. Contracts must never have side effects.
Another important point is that by convention module interfaces in Java are total, that is, they are defined for all input. In the case of incorrect input, they promise that a particular exception will be thrown. This behavior remains part of each method’s implementation and cannot be moved to the contract.
Contracts for Java is based on Modern Jass by Johannes Rieken. Rather than being a full time project it was conceived and developed in the 20% time of two software engineers and then developed further through an internship. The internship report (PDF) goes into detail about the work done and the methodologies used.
Contracts for Java was inspired by Eiffel, a language invented by Bertrand Meyer, which has built in support for contracts.
By David Morgan, Andreas Leitner and Nhat Minh Le, Contracts for Java 20% Team
Often bugs that are frustratingly elusive and hard to track down appear simple or even trivial once you have found their cause (the fault). Why are those bugs hard to track down? One possibility is that the fault is in a completely different part of the program than its symptom (the failure).

Contracted code reveals failures much closer to their fault, leaving you with a far simpler problem to solve:
Traditionally, Java programmers enforced preconditions using explicit parameter validation code in public methods, and assertions in non-public methods. Likewise, they enforced invariants and postconditions using assertions. This approach is described in detail here. Since then, new features in Java 5 have enabled a more convenient and expressive implementation of contracts.Contracts for Java is our new open source tool. Preconditions, postconditions, and invariants are added as Java boolean expressions inside annotations. By default these do nothing, but enabled via a JVM argument, they’re checked at runtime.
•@Requires,@Ensures,@ThrowEnsuresand@Invariantspecify contracts as Java boolean expressions
• Contracts are inherited from both interfaces and classes and can be selectively enabled at runtime
Contracts help you turn interface documentation into code. For example:
/**
* @param left a sorted list of elements
* @param right a sorted list of elements
* @return the contents of the two lists, merged, sorted
*/
List merge(List left, List right); Could be expressed as:
@Requires({
"Collections.isSorted(left)",
"Collections.isSorted(right)"
})
@Ensures({
"Collections.containsSame(result, Lists.concatenate(left, right))",
"Collections.isSorted(result)"
})
List merge(List left, List right); The interface is now precise and every class that implements it can be checked at runtime.
Contracts are a powerful language feature and can provide great benefit if used correctly. We recommend that newcomers find an expert to learn from or spend some time reading around the subject to pick up good habits and avoid bad ones.
One point that often surprises people is that contracts must not be used to validate data. Contracts exist to check for programmer error, not for user error or environment failures. Any difference between execution with and without runtime contract checking (apart from performance) is by definition a bug. Contracts must never have side effects.
Another important point is that by convention module interfaces in Java are total, that is, they are defined for all input. In the case of incorrect input, they promise that a particular exception will be thrown. This behavior remains part of each method’s implementation and cannot be moved to the contract.
Contracts for Java is based on Modern Jass by Johannes Rieken. Rather than being a full time project it was conceived and developed in the 20% time of two software engineers and then developed further through an internship. The internship report (PDF) goes into detail about the work done and the methodologies used.
Contracts for Java was inspired by Eiffel, a language invented by Bertrand Meyer, which has built in support for contracts.
By David Morgan, Andreas Leitner and Nhat Minh Le, Contracts for Java 20% Team

Hi, there is no .jar delivered for this project. The code in trunk does not compile. There is no documentation about dependencies. There is no documentation about how to activate/disactivate contracts... What kind of project is this? It is loosing everyone's time... Sorry !!!
ReplyDeleteHave you looked at GContracts? With closures as annotation parameters in Groovy, it's less fragile than with strings to represents those constraints.
ReplyDeleteIs this project used by Google internally ?
ReplyDeleteWhy not implement JSR 305 instead ?
Is it coordinated with the Guava project, which implements preconditions ?
It would be nice to have contract support in Java in some form. I'm a bit sceptical that the usability of Java code in Strings is good enough.
ReplyDeleteThere are multiple places where small languages are embedded in annotations. Wouldn't it be a better approach to lobby for lambda expression support in Java annotations?
It is so sad that 'contracts' have to be re-invented umpteen times and always with the same flaws.
ReplyDeleteIn 1998 I wanted to teach with Eiffel, and our very first few examples revealed that (1) sometimes Eiffel's contract system doesn't catch violations and (2) sometimes it blames the wrong contract party for a violation and (3) sometimes it explains the violation with the wrong reason sending programmers into the direction and (4) Eiffel's contract system doesn't deal with higher-order aspects of the language (how do you attach a contract to an object that may have callbacks), aka, "semantic" casts.
For a first paper on this topic, see FSE 2001. We wrote a number of follow-up papers on the meaning of contracts and how to improve them; how to deal with "first class" classes (faked by class loaders) in DSL 2010; and Google hired a PhD student from the group who is intimately familiar with our contract results.
This is actually a really fantastic piece of code. I can only hope that DBC is used more often by people. It only helps your code be more secure and more solid. This should become a standard. We'll see.
ReplyDeleteI hope this does not count as shameless self promotion.
ReplyDeleteFor those interested in some experimental results in the effectiveness of contracts in detecting faults, please, check our work in the references below:
Araujo, W. L., Briand, L. C., Labiche, Y. Enabling the Runtime Assertion Checking of Concurrent Contracts for the Java Modeling Language. In Proceedings of the 33rd ACM/IEEE International Conference on Software Engineering (ICSE '11), (to appear), ACM, Hawaii, USA, 2011
Araujo, W. L., Briand, L. C., Labiche, Y. Concurrent Contracts for Java in JML. In Proceedings of the 19th International Symposium on Software Reliability Engineering, pp. 37-46, IEEE Computer Society, 2008.
Araujo, W. Assessing the Effectiveness of Design Contracts as Test Oracles in the Detection of Faults in Concurrent Object-Oriented Software. Doctoral Thesis, Carleton University, Ottawa, 2010.
There is also the following work from our colleagues:
Briand, L. C., Labiche, Y. and Sun, H. Investigating the Use of Analysis Contracts to Improve the Testability of Object-Oriented Code. Software - Practice and Experience, 33, 7 (June 2003), 637-672.
Le Traon, Y., Baudry, B. and Jezequel, J. M. Design by contract to improve software vigilance. IEEE Transactions on Software Engineering, 32, 8 (Aug. 2006), 571-586.
@Guillaume - I had exactly GContracts in mind. Annotations in Java are to restricted and users have to become creative to work around the limitations. Spring's meta-annotations are another example where great effort is needed to get basic things done - like removing redundancy in annotations.
ReplyDeleteThis suggestion is worth million dollars.
ReplyDeleteA new facility must be created by Google. In it there must be 2 boxes. If some one pastes a HTML code. The errors in it must be validated and rectified with in seconds. The rectified HTML must appear in the second box.
And to follow-up on Matthias's excellent comment: how about joining an existing, open source tool-building effort like the Java Modeling Language community that already had dozens and dozens of man years of work, and hundreds of research papers, behind it? http://jmlspecs.org/
ReplyDeleteBuilding yet another half-working, incompatible contract-lite thing like this does the community little service, IMO.
We could really use some cycles on getting OpenJML ready for the world!
While Design By Contract is useful,
ReplyDeleteI do not think it is really an advantage over a runtime check, which seldomly costs you much performance, for example via
org.apache.commons.lang.Validate.isTrue(..) etc.
I do not want these checks to be circumventable at any time, because i want to trust them.
Also, I think most of the problems which are used by contracts should really be solved by designing better types and methods.
Any method which relies on indexing or list sizes is a flaw by itself, except if it is only allowed in a limited, private scope.
Most other problems can be used by better types. The best example for this are accidental list or array manipulations. They can easily be used by using functional collections libraries which support immutable types.
Better and simpler types: Less problems.
@AdamMan71 this may help you http://code.google.com/p/cofoja/issues/detail?id=13
ReplyDeleteif you are using linux
I'm not convinced that this is all that useful. In the above example, you could get the roughly same result by properly typing the method instead of relying on injected assertions (which might not be enabled on the JVM anyways).
ReplyDeleteFor example, why not ensure that your accepting a comparable list that can be sorted?
List merge(List left, List right)
If feels like CbD should be used only during development (assertions enabled) to ensure that no-one abuses the API - and I would have liked to see JSR 305 developed first too.
Or you could use the .Net Code Contracts which do all this with static analysis. Therefore you get proof up front that your contracts will never be violated by non exposed code, and without a performance penalty at run time. If a contract cannot be verified, warnings are given. You can then introduce appropriate branching to provide guarantees as necessary. http://research.microsoft.com/en-us/projects/contracts/
ReplyDeleteInteresting answer in the project FAQ:
ReplyDeleteIs the contract code compiled? I only see strings in annotations!
The annotation processor takes care of compiling the strings into bytecode and runs along the Java compiler, so you get static syntax and typing errors at compile time, as usual.
Not sure if example is bullet proof... Again:
ReplyDelete@Ensures({
"Collections.containsSame(result, Lists.concatenate(left, right))"
})
List merge(List left, List right);
Doesn't mean you can abandon your merge method because Lists.concatenate does the same?
Thanks to everyone for your comments! If you would like to discuss Cofoja, please head over to the Google group: https://groups.google.com/group/cofoja
ReplyDeleteThere were a lot of choices that led to Cofoja, including whether to contribute to existing projects. Modern Jass, which Cofoja is based on, was the closest thing to what we (meaning personally, not Google) wanted, and so we built on it.
I'll be very happy to discuss further on the discussion group.