or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

annotations.mdexceptions.mdindex.md
tile.json

tessl/maven-org-apache-groovy--groovy-contracts

Design by contract support for Groovy with @Invariant, @Requires, and @Ensures annotations

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/org.apache.groovy/groovy-contracts@5.0.x

To install, run

npx @tessl/cli install tessl/maven-org-apache-groovy--groovy-contracts@5.0.0

index.mddocs/

Groovy Contracts

Groovy Contracts provides design-by-contract support for the Groovy programming language through annotations that define class invariants, method preconditions, and postconditions. These contracts are automatically enforced at runtime through AST transformations that inject Java assertion statements, enabling explicit specification and verification of method contracts.

Package Information

  • Package Name: groovy-contracts
  • Package Type: maven
  • Language: Java/Groovy
  • Installation: Add dependency to your Gradle or Maven project:
dependencies {
    implementation 'org.apache.groovy:groovy-contracts:5.0.0'
}
<dependency>
    <groupId>org.apache.groovy</groupId>
    <artifactId>groovy-contracts</artifactId>
    <version>5.0.0</version>
</dependency>

Core Imports

import groovy.contracts.*

Basic Usage

@Contracted
package com.example.contracts

import groovy.contracts.*

@Invariant({ elements != null && size >= 0 })
class Stack {
    private def elements = []
    private int size = 0
    
    @Requires({ element != null })
    @Ensures({ result == old.size + 1 })
    def push(element) {
        elements.add(element)
        size++
        return size
    }
    
    @Requires({ !isEmpty() })
    @Ensures({ result != null && size == old.size - 1 })
    def pop() {
        def result = elements.removeLast()
        size--
        return result
    }
    
    def isEmpty() {
        return size == 0
    }
}

Architecture

Groovy Contracts is built around several key components:

  • Contract Annotations: Core annotations (@Invariant, @Requires, @Ensures) for defining contracts
  • AST Transformations: Compile-time processing that injects assertion statements into bytecode
  • Exception System: Specialized exception classes for different types of contract violations
  • Violation Tracking: Runtime tracking system for managing multiple contract violations
  • Inheritance Support: Contract inheritance rules for class hierarchies and interfaces

Capabilities

Contract Annotations

Core annotations for defining design-by-contract specifications on classes and methods. These annotations use closure expressions to define contract conditions.

@Target([ElementType.PACKAGE, ElementType.TYPE])
@interface Contracted

@Target([ElementType.TYPE])
@Repeatable(Invariants.class)
@interface Invariant {
    Class value()
}

@Target([ElementType.CONSTRUCTOR, ElementType.METHOD])
@Repeatable(RequiresConditions.class)
@interface Requires {
    Class value()
}

@Target([ElementType.CONSTRUCTOR, ElementType.METHOD])
@Repeatable(EnsuresConditions.class)
@interface Ensures {
    Class value()
}

Contract Annotations

Exception Handling

Exception classes thrown when contract violations occur, with specialized types for different violation scenarios and utilities for tracking multiple violations.

abstract class AssertionViolation extends AssertionError

class PreconditionViolation extends AssertionViolation
class PostconditionViolation extends AssertionViolation
class ClassInvariantViolation extends AssertionViolation
class CircularAssertionCallException extends RuntimeException

class ViolationTracker {
    static ThreadLocal<ViolationTracker> INSTANCE
    static void init()
    static void deinit()
    static boolean violationsOccurred()
    static void rethrowFirst()
    static void rethrowLast()
}

Exception Handling

Types

Annotation Containers

@interface Invariants {
    Invariant[] value()
}

@interface RequiresConditions {
    Requires[] value()
}

@interface EnsuresConditions {
    Ensures[] value()
}

Contract Variables

Special variables available in contract expressions:

  • Preconditions (@Requires): Access to method arguments and class fields
  • Postconditions (@Ensures): Access to method arguments, class fields, result (return value), and old (map of previous field values)
  • Invariants (@Invariant): Access to class fields only

Supported Old Value Types

The old variable in postconditions supports automatic cloning for:

  • Primitive types and their wrapper classes
  • Cloneable types
  • BigInteger and BigDecimal
  • String and GString

Contract Inheritance Rules

  • Class Invariants: Combined with parent invariants using logical AND
  • Preconditions: Combined with parent preconditions using logical OR (weakening)
  • Postconditions: Combined with parent postconditions using logical AND (strengthening)

JVM Integration

Contracts are implemented as Java assertion statements and can be controlled using standard JVM assertion parameters:

  • Enable assertions: -ea or -enableassertions
  • Disable assertions: -da or -disableassertions
  • Package-specific control: -ea:com.example.contracts.*

API Stability

Important: All contract annotations (except @Contracted) are marked with @Incubating, indicating they are subject to breaking changes in future versions until the API is stabilized. The exception classes and ViolationTracker are not marked as incubating and are considered stable.