我有很多groovy脚本,用GMaven编译(位于src/main/groovy/somepackage
),每个脚本都有run(String, String)
函数,没有类:
// script1.groovy
def run(String name, String arg) {
// body
}
// script2.groovy
def run(String name, String arg) {
// body
}
我可以使用Reflections库找到它们并解析它们的类型:
final Set<String> scripts = new Reflections(
"somepackage",
new SubTypesScanner(false)
).getAllTypes();
for (String script : scripts) {
run(Class.forName(name));
}
然后我遇到了一些执行问题:我无法创建scipt实例,因为它没有公共构造函数(只有私有的groovy.lang.Reference
参数)而且我不能找到此类型的run
方法。
问题:如何使用反射正确地从Java执行编译的groovy脚本(使用单个方法,没有类)?
答案 0 :(得分:1)
您可以使用以下命令从给定的包加载已编译的Groovy脚本:
Reflections.getSubTypesOf(groovy.lang.Script.class)
它返回Set<Class<? extends Script>>
,因此您可以迭代这些类,实例化它们并使用Class.invokeMethod(String name, Object args)
注意:您无法像
script.run(string1, string2)
那样调用此方法,因为此方法在父groovy.lang.Script
类中不存在。
您可以在下面找到一个示例:
import groovy.lang.Script;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import java.util.Set;
public class LoadGroovyScriptExample {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Set<Class<? extends Script>> scripts = new Reflections("somepackage", new SubTypesScanner(false))
.getSubTypesOf(Script.class);
for (Class<? extends Script> script : scripts) {
script.newInstance().invokeMethod("run", new Object[] { "test", "123" });
}
}
}
somepackage / script1.groovy
package somepackage
def run(String name, String arg) {
println "running script1.groovy: ${name}, ${arg}"
}
somepackage / script2.groovy
package somepackage
def run(String name, String arg) {
println "running script2.groovy: ${name}, ${arg}"
}
[main] INFO org.reflections.Reflections - Reflections took 93 ms to scan 1 urls, producing 1 keys and 2 values
running script2.groovy: test, 123
running script1.groovy: test, 123