fsteeg.com | notes | tags

Setting up Contracts for Java in Eclipse
Date: 2011-02-07 | Tagged: eclipse, java, programming

Cross-posted to: https://fsteeg.wordpress.com/2011/02/07/setting-up-contracts-for-java-in-eclipse/

On Friday, Contracts for Java was announced on the Google Open Source Blog. Learning about this at the beginning of the weekend was perfect timing for me: I had time to check it out, and while setting it up was some work, I was hooked right away.

Now something like Contracts for Java is only really useful if it is well integrated into the tools you use everyday - which in my case is Eclipse. Eclipse allows many levels of integration, and I quickly had it working by running javac as an external tool - which is OK, but not ideal, since it requires running the tool manually after every change to the annotations, and doesn't give in-place error messages. I quickly found out Eclipse has support for custom annotation processing. I had to fiddle a little until I got that configured properly with Contracts for Java so I thought I do a quick write-up so other people can try this cool new tool in Eclipse.

Contracts for Java doesn't provide any binary downloads yet, so my first step was to build a Jar. To use it, create a Java project, and add cofoja-latest.jar and asm-all-3.3.1.jar to the build path. Then add some code that uses contract annotations (copy and paste the code below into the src folder of the project):

import com.google.java.contract.Ensures;
import com.google.java.contract.Requires;

public class Contracts { public static void main(String[] args) { System.out.println(new Numbers().add(-10, 5)); } }

class Numbers { @Requires({ "c > 0", "b > 0" }) @Ensures({ "result > a", "result > b" }) int add(int a, int b) { return a - b; } }

Next, configure the annotation processing in the project properties > Java Compiler > Annotation Processing. To make Contracts for Java work with the Eclipse Java compiler, currently some specific properties have to be set up: set the com.google.java.contract.classpath property to the location of your cofoja-latest.jar and the com.google.java.contract.classoutput property to the location of your project's src or separate bin folder (both relative to the project root, using the %PROJECT.DIR% variable):

If your project uses multiple Jars they currently have to be given with absolute paths as the com.google.java.contract.classpath value, separated with ':' on Unix or ';' on Windows. Next, make sure you have set up your workspace to refresh automatically in Preferences > General > Workspace to make Eclipse see the resources generated by the annotation processor. Then, add the cofoja-latest.jar to the project properties > Java Compiler > Annotation Processing > Factory Path:

Now issues in the annotation values are reported in the editor, like variables that cannot be found, e.g. for our code above:

To have the contracts checked at runtime, add -javaagent:cofoja-current.jar to the VM arguments of your run configuration:

Now when running, we are made aware of the violated precondition in our code:

After we fix the call violating the precondition to new Numbers().add(10, 5); we now see our implementation of add does not fulfill the postcondition:

After fixing our implementation to return a + b; the code now runs without errors. For further information on using Contracts for Java check out the project wiki. General information on design by contract can be found elsewhere.