如何使用 GroovyClassLoader 加载 GroovyCompiled 类或如何在 loadClass 的情况下设置委托

问题描述

我正在尝试加载在构建期间编译并作为 .class 文件放置在类路径中的类。为此,我尝试了

GroovyClassLoader gos = new GroovyClassLoader();

gos.loadClass("className");

这将成功加载 java 代码中的类文件,但它使用 AppClassLoader 加载这个而不是 GroovyClassLoader。

我知道 GroovyClassLoader 在内部使用 AppClassLoader 找到它。 但是有区别:

因为 gos.parseClass(string) 会给我们一个从 GroovyClassLoader 解析的类。

虽然在第二种情况(parseClass)中实例化类文件给了我们设置委托的委托,但在第一种情况(loadClass)中,我们没有任何。

如何在执行loadClass或通过GroovyClassLoader以任何方式加载类文件后设置委托。

Load Class

解决方法

Groovy Compiler 编译 groovy 文件(HelloWorld.dsl)并将它们放在类路径中,创建同名的 .class 文件(HelloWorld.class)。 默认情况下编译的类文件(打开字节码)有与类文件同名的类(HelloWorld)。

这个类将从 Script 扩展而来。现在,如果您尝试使用加载此类文件 gos.loadClass("HelloWorld").newInstance() ,它将为我们提供一个 Script 对象,我们将无法将委托设置为 Script 对象。它也不会被转换成 DelegatingScript。

要使您的编译类从 DelegatingScript 扩展,请将其添加到 dsl 文件 @groovy.transform.BaseScript DelegatingScript delegatingScript 的顶部。 Groovy 编译器会理解这一点,并使类文件从 DelegatingScript 扩展,而不是像以前那样从 Script 扩展。

现在,当您尝试使用 gos.loadClass("HelloWorld").newInstance() 加载类时,它将提供 DelegatingScript 对象而不是 Script 对象。对于这个对象,我们可以设置委托并运行脚本。

如果您使用 parseClass,要使用委托,我们需要将 ScriptBaseClass 作为 DelegatingScript 设置为 compilerConfiguration。现在如果你尝试 gos.parseClass(dslText).newInstance() ,它会直接给出一个 DelegatingScript 对象,我们可以设置一个委托并运行脚本。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...