Ice09
Ice09

Reputation: 9101

GroovyInterceptable does not work on methods with no arguments

A simple code snippet which uses invokeMethod in combination with GroovyInterceptable. If the nested simpleMethod2 has an argument, it works - otherwise not.

I have not found an explanation, so I assume it should work with nested methods without arguments as well?

class SimpleFlow implements GroovyInterceptable {

    def invokeMethod(String name, args) {
        System.out.println("time before ${name} called: ${new Date()}")

        def calledMethod = SimpleFlow.metaClass.getMetaMethod(name, args)
        calledMethod?.invoke(this, args)

        System.out.println("time after ${name} called: ${new Date()}\n")
    }

    void simpleMethod1(){
        System.out.println("simpleMethod1() called")
        simpleMethod2Nested()
    }

    // works well when using an argument
    void simpleMethod2Nested(){
        System.out.println("simpleMethod2Nested")
    }

    public static void main(String[] args) {
        def flow = new SimpleFlow()
        flow.simpleMethod1()
    }
}

Output without argument:

time before simpleMethod1 called: Tue Jun 21 04:16:41 CEST 2011
simpleMethod1() called
simpleMethod2Nested
time after simpleMethod1 called: Tue Jun 21 04:16:41 CEST 2011`

Upvotes: 1

Views: 722

Answers (1)

denis.solonenko
denis.solonenko

Reputation: 11775

Not yet sure if it's a bug or a feature :) (most probably a bug because method with args do work as expected - please do raise a bug in groovy jira). Meanwhile you can fix it by adding a variable self which references to this and use it to call the nested method:

class SimpleFlow implements GroovyInterceptable {

def self = this

def invokeMethod(String name, Object args) {
    // same as original
}

void simpleMethod1(){
    System.out.println("simpleMethod1() called")
    self.simpleMethod2Nested() // note the use of self
}

// works well when using an argument
void simpleMethod2Nested(){
    System.out.println("simpleMethod2Nested")
}

public static void main(String[] args) {
    def flow = new SimpleFlow()
    flow.simpleMethod1()
}

}

Output:

time before simpleMethod1 called: Tue Jun 21 13:32:44 GMT+08:00 2011
simpleMethod1() called
time before simpleMethod2Nested called: Tue Jun 21 13:32:44 GMT+08:00 2011
simpleMethod2Nested
time after simpleMethod2Nested called: Tue Jun 21 13:32:44 GMT+08:00 2011
time after simpleMethod1 called: Tue Jun 21 13:32:44 GMT+08:00 2011

Upvotes: 2

Related Questions