user626528 user626528 - 1 month ago 19
Groovy Question

Using `evaluate` function. Why it doesn't work?

This code:

evaluate ("def test() { println \"Test is successful!\" }")
test()


results in exception:


FATAL: No signature of method: script1409644336796288198097.test() is applicable for argument types: () values: []
Possible solutions: use([Ljava.lang.Object;), getAt(java.lang.String), use(java.util.List, groovy.lang.Closure), use(java.lang.Class, groovy.lang.Closure), wait(), wait(long)
groovy.lang.MissingMethodException: No signature of method: script1409644336796288198097.test() is applicable for argument types: () values: []
Possible solutions: use([Ljava.lang.Object;), getAt(java.lang.String), use(java.util.List, groovy.lang.Closure), use(java.lang.Class, groovy.lang.Closure), wait(), wait(long)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)
...


What I'm doing wrong?

Answer

That script evaluation results in null. You should either return something or execute the script and return the result.

An example returning a closure instead of defining a method:

test = evaluate ('return { "Test is successful!" }')
assert test() == "Test is successful!"

And an example where the script executes the method itself:

result = evaluate 'def test() { "eval test" }; return test()'
assert result == "eval test"

If you cannot change the script code, you may parse a class from the script, create a new object, and then execute the test() method:

def parent = getClass().getClassLoader()
def loader = new GroovyClassLoader(parent)
def clazz = loader.parseClass('def test() { "new class definition" }');

obj = clazz.newInstance()
assert obj.test() == "new class definition"