Possibility to disable the property syntax for accessing a getter in groovy?

436 views Asked by At

Let's I have a groovy class like:

class SomeClass {
    String myProperty = 'foo'
}

Usually in groovy is will be totally valid to access the value using the property name or the getter - which usually gives the same result for SomeClass:

SomeClass someClass = new SomeClass()
assert someClass.myProperty == 'foo'
assert someClass.getMyProperty() == 'foo'

However - due to a flaw in the Jenkins Pipeline implementation - sometimes(!) you are forced to use the getter - as the plain property access will not work (when using some class hierarchy), see: JENKINS-47143. Bad thing is that the same code may work for some jobs while it doesn't for others:

SomeClass someClass = new SomeClass()
assert someClass.myProperty == 'foo' // sometimes throws 'property not found' error
assert someClass.getMyProperty() == 'foo'

Now I already have couple of unit tests for our Jenkins shared library - but what is missing would be a way to detect a property access, in short: A way to prohibit the property access so the unit tests will already complain in advance.

1

There are 1 answers

0
Matias Bjarland On BEST ANSWER

The following code:

class SomeClass { 
  String myProperty = 'foo'
}

SomeClass.metaClass.getProperty = { String name -> 
  throw new RuntimeException("tried to get property ${name}, property access only allowed via getXX() methods")
}

def s = new SomeClass()

println(s.myProperty)       // a
println(s.getMyProperty())  // b

will throw an exception for line a but not throw an exception for line b. I suspect this will not be possible if SomeClass was written in java, but assuming a groovy class this could be a way to accomplish what you want.

Running the above will result in:

─➤ groovy solution.groovy
Caught: java.lang.RuntimeException: tried to get property myProperty, property access only allowed via getXX() methods
java.lang.RuntimeException: tried to get property myProperty, property access only allowed via getXX() methods
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
...