Skip to content


Subversion checkout URL

You can clone with
Download ZIP


andresteingress edited this page · 44 revisions

Welcome to GContracts – Programming by Contract with Groovy!

Flattr this

This project aims to provide contract annotations that support the specification of class-invariants, pre- and post-conditions on methods and loop invariants towards better software quality in Groovy/Grails projects.

GContracts 1.2 supports the following features:

  • definition of class invariants, pre- and post-conditions via @Invariant, @Requires and @Ensures

    @Requires({ item?.size() > 0 }) def sendItem(def item) { … }

    @Ensures({ result != null }) def receiveItem() { … }

    @Invariant({ name.size() in [1..5] })
    class PersonalIdentification {
    def name
    // …
  • inheritance of class invariants, pre- and post-conditions of concrete predecessor classes

    class Rocket {

    @Ensures({ old.speed < speed })
    def accelerate() { … }

    class BetterRocket extends Rocket {

    @Ensures({ old.speed + 100 < speed })
    def accelerate() { … }

  • inheritance of class invariants, pre- and post-conditions in implemented interfaces

  • usage of old and result variable in post-condition assertions
  • assertion injection in Plain Old Groovy Objects (POGOs)
  • human-readable assertion messages, based on Groovy power asserts
  • package- or class-level enabling of contracts via @AssertionsEnabled
  • annotation contracts: a way to reuse reappearing contract elements in a project
  • detection of cycles in assertion conditions

The Stack Example

Up to now the project provides 3 annotations: @Invariant, @Require and @Ensures – all of them work with so-called closure annotations, allowing to specify arbitrary code pieces as annotation parameters:

@Grab(group='org.gcontracts', module='gcontracts', version='[1.1.2,)')
import org.gcontracts.annotations.*

@Invariant({ elements != null })
class Stack {

    private List elements

    @Ensures({ is_empty() })
    public Stack()  {
        elements = []

    @Requires({ preElements?.size() > 0 })
    @Ensures({ !is_empty() })
    public Stack(List preElements)  {
        elements = preElements

    def boolean is_empty()  {

    @Requires({ !is_empty() })
    def last_item()  {

    def count() {

    @Ensures({ result == true ? count() > 0 : count() >= 0  })
    def boolean has(def item)  {

    @Ensures({ last_item() == item })
    def put(def item)  {

    @Requires({ !is_empty() })
    @Ensures({ last_item() == item })
    def replace(def item)  {

    @Requires({ !is_empty() })
    @Ensures({ result != null })
    def remove()  {

    def String toString() { elements.toString() }

The example above specifies a class-invariant and methods with pre- and post-conditions. Note, that preconditions may reference method arguments and post-conditions have access to the method’s result with the result variable and old instance variables values with old.

Indeed, Groovy AST transformations change these assertion annotations into Java assertion statements (can be turned on and off with a JVM param) and inject them at appropriate places, e.g. class-invariants are used to check an object’s state before and after each method call.

How to add GContracts to a project

In order to use GContracts in a Maven project, following this wiki’s guide (Wiki page: Maven).

Otherwise, download the GContracts binary from github’s download section and throw it in the application class path. groovyc automatically detects the jar and injects GContracts assertions.


The project is currently in alpha phase and not ment to be used in production environments, but feel free if you want to contribute and improve things.

Something went wrong with that request. Please try again.