java - 在运行时用 Java 编译 Groovy 类

标签 java groovy runtime-compilation

我成功地能够在运行时用 Java 编译 Groovy 并将其存储在数据库中并提取出来。如果 Groovy 类具有内部类或内部枚举,我将无法对其进行编译。有没有人像这样成功编译 Groovy 代码并包含内部类/枚举并能够通过类名提取脚本?

例如,我想加载下面显示的包含内部类的“测试”脚本,并在运行时运行该脚本。

编译器代码:

public byte[] compileGroovyScript(final String className, final String script) {
    byte[] compiledScriptBytes = null;
    CompilationUnit compileUnit = new CompilationUnit();
    compileUnit.addSource(className, script);
    compileUnit.compile(Phases.CLASS_GENERATION);

    for (Object compileClass : compileUnit.getClasses()) {
        GroovyClass groovyClass = (GroovyClass) compileClass;
        compiledScriptBytes = groovyClass.getBytes();
    }

    return compiledScriptBytes;
}

提取脚本的代码:

public Class getGroovyScript(final String className, final byte[] script) {
    Class clazz = null;

    try (GroovyClassLoader classLoader = new GroovyClassLoader(this.getClass().getClassLoader())) {
        clazz = classLoader.defineClass(className, script);
    } catch (IOException e) {
    } catch (Exception e) {
    }

    return clazz;
}

运行脚本的代码:

Class groovyClass = app.getGroovyScript(className, compiledScript);
TestScript script = (TestScript) groovyClass.newInstance();
System.out.println(script.getMessage());

常规脚本:

import com.groovy.groovy.TestScript

class Test implements TestScript {

    String getMessage() {
        [1..10].each(){
            println it
        }
        return "Jello"
    }
}

最佳答案

从描述中不清楚您为什么要自己进行编译。如果您可以让 Groovy 为您做这件事,那么整个事情就可以简化为如下所示:

String script = // string containing the script you want to parse

GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
Class theParsedClass = groovyClassLoader.parseClass(script);

关于java - 在运行时用 Java 编译 Groovy 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23088401/

相关文章:

java - JFugue:加载的 MIDI 文件未使用正确的乐器播放

java - 特定包的完全限定类名?

java - XmlSlurper获取节点值说明

java - 从 XML 解析数据的 Groovy 语法

java - 动态程序更新、运行时编译和类加载器

java - 使用 Spring MVC 上传文件

java - 函数返回后成员变量为null?

grails - 将Xml配置转换为resource.groovy

c# - Roslyn,如何在运行时在脚本中实例化一个类并调用该类的方法?

C++ 让程序重写自己