我正在尝试获得一个动态生成的groovy脚本,以继承类并实现调用java程序的接口。我传入了评估groovy脚本的类的类加载器,但没有用。我想知道我是否可以问一位Groovy专家我可能做错了什么?
代码如下所示。在这两种情况下,在评估脚本时,都无法识别在调用代码上下文中定义的类"X"。我收到的消息如下"Script1.groovy:3:无法解析类X"
import org.junit.Test
import java.lang.reflect.Method
public class GroovyPuzzler {
public static class X {
String hello = "said-hello"
}
@Test
public void test1() {
GroovyShell shell = new GroovyShell(this.getClass().getClassLoader());
Object script = shell.evaluate(
"""
def sayHello() {
println new X().hello;
}
return this
""");
Method m = script.getClass().getMethod("sayHello");
m.invoke(script);
}
@Test
public void test2() {
String script =
"""
public class Boo {
def sayHello() {
println new X().hello;
}
}
"""
ClassLoader parent = getClass().getClassLoader();
GroovyClassLoader loader = new GroovyClassLoader(parent);
Class groovyClass = loader.parseClass(script);
GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
Object[] args = {};
groovyObject.invokeMethod("sayHello", args);
}
}
不知道如何从以这种方式调用的脚本中捕获输出(SystemOutputInterceptor
???),所以我将println
更改为throw
,以说明它确实有效。
您需要做的是import
您想要使用的类。代码如下:
package sample
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.customizers.ImportCustomizer
import org.junit.Test
import java.lang.reflect.Method
public class GroovyPuzzler {
public static class X {
def hello2() {
throw new RuntimeException("bang!")
}
}
@Test
public void test1() {
def customizer = new ImportCustomizer()
customizer.addImport('X', 'sample.GroovyPuzzler.X')
def configuration = new CompilerConfiguration()
configuration.addCompilationCustomizers(customizer)
GroovyShell shell = new GroovyShell(configuration)
Object script = shell.evaluate(
"""
def sayHello() {
new X().hello2()
}
return this
"""
)
try {
Method m = script.getClass().getMethod("sayHello")
m.invoke(script)
fail()
} catch (Exception e) {
assertTrue(e.cause.message.equals('bang!'))
}
}
}