Adjusting for Groovy JavaBeans specification compatibility changes
Groovy 3 is more compliant with the JavaBeans specification for one edge case scenario involving any field having a name starting with an uppercase letter. This change has an impact on the handling of properties.
Groovy properties
The definition of properties according to the Groovy public documentation is:
A property is an externally visible feature of a class. Rather than just using a public field to represent such features (which provides a more limited abstraction and would restrict refactoring possibilities), the typical approach in Java is to follow the conventions outlined in the JavaBeans Specification, i.e. represent the property using a combination of a private backing field and getters/setters. Groovy follows these same conventions but provides a simpler way to define the property.
The code sample below will generate the following:
-
A backing
private String name
field, a getName and a setName method. -
A backing
private int age
field, a getAge and a setAge method.
class Person {
String name
int age
}
By convention, Groovy also recognizes properties even if there is no backing field, provided there are getters or setters that follow the Java Beans specification.
class PseudoProperties {
//1. a pseudo property "name"
void setName(String name) {}
String getName() {}
//2. a pseudo read-only property "age"
int getAge() { 42 }
//3. a pseudo write-only property "groovy"
void setGroovy(boolean groovy) { }
}
def p = new PseudoProperties()
p.name = 'Foo' // uses (1)
assert p.age == 42 // uses (2)
p.groovy = true // uses (3)
Groovy 3 breaking change
In Groovy 3 the handling of properties that start with an uppercase letter has changed to be more compliant with the JavaBeans specification.
The way how properties are mapped to the accessor method has changed. In groovy 2 it was possible to access the field instead of the accessor methods in some scenarios as shown below:
Groovy 2
|
Groovy 3
|
A similar situation occurs when you use static properties:
Groovy 2
|
Groovy 3
|
This breaking change doesn’t affect classes where accessor methods are not overwritten.
Recommendation
To make existing workflow scripts compatible with Groovy 3, we recommend using lowercase property names, except in when the property name is all uppercase:
class A {
private String X = 'fieldX'
private String XML = 'fieldXML'
String getX() { 'X' }
String getXML() { 'XML' }
}
new A().with {
assert x == 'X' // instead of using uppercase X property
assert XML == 'XML' // in this case using XML property is the only way
}