我有很多用GMaven编译的groovy脚本(位于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 实例,因为它没有公共(public)构造函数(只有带有 groovy.lang.Reference
参数的私有(private)构造函数),我可以'找不到此类型中的 run
方法。
问题:如何正确使用反射从 Java 执行已编译的 groovy 脚本(使用单一方法且没有类)?
最佳答案
您可以使用以下命令从给定包加载已编译的 Groovy 脚本:
Reflections.getSubTypesOf(groovy.lang.Script.class)
它返回 Set<Class<? extends Script>>
因此您可以迭代这些类,实例化它们并使用 Class.invokeMethod(String name, Object args)
调用方法
ATTENTION: you wont be able to call this method like
script.run(string1, string2)
, because this method does not exist in parentgroovy.lang.Script
class.
下面是一个示例:
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
关于java - 通过反射从java执行编译的groovy脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49915542/