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
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).
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 particularv
which stores versions of used libraries andcofoja
- 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 bycompileContracts
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 usescom.google.java.contract.core.apt.AnnotationProcessor
to process CoFoJa annotations and produce*.contract
files.