2012-06-13

CoFoJa setup with Gradle

Build tool

For all my new projects I use Gradle and it's really awesome. Some time ago I did a research, and tried a few tools. Besides Gradle I also looked at Apache Buildr and the Simple Build Tool. Buildr seems pretty similar to Gradle but I had some problems running it with JRuby and the sbt for me is really user unfriendly.

Contracts

The idea is pretty simple. There are few kinds of contracts but the most important are preconditions and postconditions for your methods. We consider that when these are satisfied the method works as expected. Precondition is the obligation of the caller to the callee. We can specify what conditions for the parameters and state of the object have to be met in order to run the method. The postcondition on the other hand states what is satisfied after the call returns.

for Java

Unfortunately contracts are not a builtin feature of Java. Luckily for us there exists a decent implementation which we can use. Enter CoFoJa! Let's start with a canonical example from Eiffel tutorial implemented with CoFoJa:
The example is pretty simple. There is a Time interface with two methods - setter and getter for the hour property. The contract on both methods makes it pretty obvious that the only acceptable values for hour are integers in the range between 0 and 23 (inclusive). Moreover, the implicit property contract was made explicit (the property contract states that after setting a property and then retrieving it, you get the same value).
There are few technical issues worth mentioning here. First of all contracts are written as strings in annotations, not in the code itself. You might discuss is this a good or a bad thing. For me there are far more pros than cons. First of all you can write your contracts on interfaces (and they get inherited). That adds a lot of power since contracts are part of the specification (hence they belong to the interface) not the implementation. Moreover this feature helps you stay DRY. The cons is that when you're not using a good IDE you don't get any syntax highlighting or other cool features IDEs provide. However in IntelliJ (which I'm a big fan of) you can inject a language into content of annotation string parameters (and many other places). Then autocompletion and syntax highlighting works like magic (again).

The setup

Let's start with a working build.gradle example and analyze it piece by piece.
Sorry for the long listing (well, not that long actually - try do the same with Maven). Let's start from the beginning.

  • First two lines apply plugins for integrating with Java and IntelliJ (and are kind of irrelevant for this topic).
  • repositories block defines Maven Central as the main dependencies repository.
  • project.ext defines few constants inside. In particular v which stores versions of used libraries and cofoja - the path to the cofoja.jar in your VCS (unfortunately CoFoJa is not available in Maven Central and any other repository as far as I'm concerned so in order to use it at the moment you have to download it from the project downloads page and put it in source control). After that there is a file collection of contract compilation outputs (yes! contracts get compiled separately) which is produced by compileContracts task.
  • After dependencies block there is a config for Java compilation task which turns off contract compilation (we want them compiled by separate task having output in a separate directory).
  • Finally there is compileContracts custom task which uses com.google.java.contract.core.apt.AnnotationProcessor to process CoFoJa annotations and produce *.contract files.
That would be it for compiling contracts. This Gradle build file is configured to enable contracts only during tests (which in my opinion is a good practice). To enable contracts you should pass a java agent to your JVM (which is done in test configuration block at the end). Similar configuration using Ant can be found on the CoFoJa wiki.

No comments:

Post a Comment