此代码:
evaluate ("def test() { println \"Test is successful!\" }")
test()
导致异常:
致命:没有方法签名:script1409644336796288198097.test()适用于参数类型:()值:[] 可能的解决方案:使用([Ljava.lang.Object;),getAt(java.lang.String),使用(java.util.List,groovy.lang.Closure),使用(java.lang.Class,groovy.lang。关闭),wait(),等待(长) groovy.lang.MissingMethodException:没有方法签名:script1409644336796288198097.test()适用于参数类型:()值:[] 可能的解决方案:使用([Ljava.lang.Object;),getAt(java.lang.String),使用(java.util.List,groovy.lang.Closure),使用(java.lang.Class,groovy.lang。关闭),wait(),等待(长) 在org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55) ...
我做错了什么?
答案 0 :(得分:12)
该脚本评估结果为null。您应该返回一些内容或执行脚本并返回结果。
返回闭包而不是定义方法的示例:
test = evaluate ('return { "Test is successful!" }')
assert test() == "Test is successful!"
脚本执行方法本身的示例:
result = evaluate 'def test() { "eval test" }; return test()'
assert result == "eval test"
如果您无法更改脚本代码,可以parse a class from the script创建一个新对象,然后执行test()
方法:
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"
答案 1 :(得分:0)
您可以使用ExpandoMetaClass将动态闭包添加到您自己的类中。您需要事先解析字符串,将其拆分为函数名,参数和代码。
methodName = "test"
methodArgs = []
methodCode = """println "Hello World!" """
this.metaClass."$methodName"{ code, args ->
evaluate(code)
}
然后你可以这样做:
"$methodName"(code, arguments)
或
test(code, arguments)
获取输出Hello World!
您可以在此处阅读有关ExpandoMetaClass的更多信息http://groovy.codehaus.org/ExpandoMetaClass
答案 2 :(得分:0)
如果变量具有未声明的类型,则为it goes into the script binding。绑定对所有方法都是可见的,这意味着共享数据。
evaluate()
is a helper method允许使用this
脚本绑定作为变量范围来动态评估groovy表达式。
在变量绑定中,您可以declare a closure不接受任何参数,并且必须限制为不带参数的调用。
考虑到所有这些,这里的脚本按预期工作。
evaluate ("test = { -> println \"Test is successful!\" }")
test()
答案 3 :(得分:0)
除了所有其他答案之外,如果您不想更改代码的结构,只需在groovy-string的末尾使用return this
:
lib = evaluate ("def test() { println \"Test is successful!\" }; return this")
lib.test()