0
# Groovy Contracts
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: groovy-contracts
7
- **Package Type**: maven
8
- **Language**: Java/Groovy
9
- **Installation**: Add dependency to your Gradle or Maven project:
10
11
```gradle
12
dependencies {
13
implementation 'org.apache.groovy:groovy-contracts:5.0.0'
14
}
15
```
16
17
```xml
18
<dependency>
19
<groupId>org.apache.groovy</groupId>
20
<artifactId>groovy-contracts</artifactId>
21
<version>5.0.0</version>
22
</dependency>
23
```
24
25
## Core Imports
26
27
```groovy
28
import groovy.contracts.*
29
```
30
31
## Basic Usage
32
33
```groovy
34
@Contracted
35
package com.example.contracts
36
37
import groovy.contracts.*
38
39
@Invariant({ elements != null && size >= 0 })
40
class Stack {
41
private def elements = []
42
private int size = 0
43
44
@Requires({ element != null })
45
@Ensures({ result == old.size + 1 })
46
def push(element) {
47
elements.add(element)
48
size++
49
return size
50
}
51
52
@Requires({ !isEmpty() })
53
@Ensures({ result != null && size == old.size - 1 })
54
def pop() {
55
def result = elements.removeLast()
56
size--
57
return result
58
}
59
60
def isEmpty() {
61
return size == 0
62
}
63
}
64
```
65
66
## Architecture
67
68
Groovy Contracts is built around several key components:
69
70
- **Contract Annotations**: Core annotations (@Invariant, @Requires, @Ensures) for defining contracts
71
- **AST Transformations**: Compile-time processing that injects assertion statements into bytecode
72
- **Exception System**: Specialized exception classes for different types of contract violations
73
- **Violation Tracking**: Runtime tracking system for managing multiple contract violations
74
- **Inheritance Support**: Contract inheritance rules for class hierarchies and interfaces
75
76
## Capabilities
77
78
### Contract Annotations
79
80
Core annotations for defining design-by-contract specifications on classes and methods. These annotations use closure expressions to define contract conditions.
81
82
```groovy { .api }
83
@Target([ElementType.PACKAGE, ElementType.TYPE])
84
@interface Contracted
85
86
@Target([ElementType.TYPE])
87
@Repeatable(Invariants.class)
88
@interface Invariant {
89
Class value()
90
}
91
92
@Target([ElementType.CONSTRUCTOR, ElementType.METHOD])
93
@Repeatable(RequiresConditions.class)
94
@interface Requires {
95
Class value()
96
}
97
98
@Target([ElementType.CONSTRUCTOR, ElementType.METHOD])
99
@Repeatable(EnsuresConditions.class)
100
@interface Ensures {
101
Class value()
102
}
103
```
104
105
[Contract Annotations](./annotations.md)
106
107
### Exception Handling
108
109
Exception classes thrown when contract violations occur, with specialized types for different violation scenarios and utilities for tracking multiple violations.
110
111
```groovy { .api }
112
abstract class AssertionViolation extends AssertionError
113
114
class PreconditionViolation extends AssertionViolation
115
class PostconditionViolation extends AssertionViolation
116
class ClassInvariantViolation extends AssertionViolation
117
class CircularAssertionCallException extends RuntimeException
118
119
class ViolationTracker {
120
static ThreadLocal<ViolationTracker> INSTANCE
121
static void init()
122
static void deinit()
123
static boolean violationsOccurred()
124
static void rethrowFirst()
125
static void rethrowLast()
126
}
127
```
128
129
[Exception Handling](./exceptions.md)
130
131
## Types
132
133
### Annotation Containers
134
135
```groovy { .api }
136
@interface Invariants {
137
Invariant[] value()
138
}
139
140
@interface RequiresConditions {
141
Requires[] value()
142
}
143
144
@interface EnsuresConditions {
145
Ensures[] value()
146
}
147
```
148
149
### Contract Variables
150
151
Special variables available in contract expressions:
152
153
- **Preconditions (@Requires)**: Access to method arguments and class fields
154
- **Postconditions (@Ensures)**: Access to method arguments, class fields, `result` (return value), and `old` (map of previous field values)
155
- **Invariants (@Invariant)**: Access to class fields only
156
157
### Supported Old Value Types
158
159
The `old` variable in postconditions supports automatic cloning for:
160
- Primitive types and their wrapper classes
161
- `Cloneable` types
162
- `BigInteger` and `BigDecimal`
163
- `String` and `GString`
164
165
## Contract Inheritance Rules
166
167
- **Class Invariants**: Combined with parent invariants using logical AND
168
- **Preconditions**: Combined with parent preconditions using logical OR (weakening)
169
- **Postconditions**: Combined with parent postconditions using logical AND (strengthening)
170
171
## JVM Integration
172
173
Contracts are implemented as Java assertion statements and can be controlled using standard JVM assertion parameters:
174
- Enable assertions: `-ea` or `-enableassertions`
175
- Disable assertions: `-da` or `-disableassertions`
176
- Package-specific control: `-ea:com.example.contracts.*`
177
178
## API Stability
179
180
**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.