Reputation: 683
The following Groovy trait implements the GroovyInterceptable
interface to allow execution of code before and after method calls.
trait Bar implements GroovyInterceptable {
def bar = "bar"
@Override
invokeMethod(String name, Object args) {
System.out.println(bar)
metaClass.getMetaMethod(name, args).invoke(this, args)
}
def doSomething() {
}
}
The following class implements the trait Bar
.
class Foo implements Bar {
}
Have a look at the following code.
def foo = new Foo()
foo.doSomething()
The call to doSomething()
is being intercepted by invokeMethod()
. A java.lang.StackOverflowError
occurs because accessing the property bar
inside invokeMethod()
implicitly makes a call to the getter of bar
which in turn is intercepted by invokeMethod()
just trying to access bar
again.
How can I access a class property inside invokeMethod
without calling this property's getter or setter?
In combination with the trait using this.@bar
to access the property does not work.
The code metaClass.getMetaMethod(name, args).invoke(this, args)
to invoke the intercepted method could be incorrect although it works when using the trait logic directly inside a class.
Edit for Solution:
The accepted answer contributed by user Opal works like a charm in a script environment. Since the trait is part of a larger project and defined in its own file I made it work like this:
package com.example.project
trait Bar implements GroovyInterceptable {
def bar = "bar"
@Override
invokeMethod(String name, Object args) {
System.out.println(this.com_example_project_Bar__bar)
metaClass.getMetaMethod(name, args).invoke(this, args)
}
def doSomething() {
}
}
Upvotes: 1
Views: 341
Reputation: 84784
It turns out that there's no need to use @
for direct field access:
trait Bar implements GroovyInterceptable {
def bar = "bar"
@Override
invokeMethod(String name, Object args) {
System.out.println(Bar__bar)
metaClass.getMetaMethod(name, args).invoke(this, args)
}
def doSomething() {
}
}
class Foo implements Bar {
}
def foo = new Foo()
foo.doSomething()
Upvotes: 2