Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile Groovy class at runtime in Java

I am successfully able to compile Groovy in Java at runtime and store it in a database and pull it out. I can't compile a Groovy class if it has inner classes or an inner enum. Has anyone successfully compiled Groovy code like this and included inner classes/enums and able to pull the script out by classname?

For example, I want to load the "Test" script shown below that contains inner classes and run the script at run time.

Compiler code:

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;
}

Code to pull script out:

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;
}

Code to run the script:

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

Groovy script:

import com.groovy.groovy.TestScript

class Test implements TestScript {

    String getMessage() {
        [1..10].each(){
            println it
        }
        return "Jello"
    }
}
like image 491
ColinMc Avatar asked Apr 15 '14 15:04

ColinMc


People also ask

Does Groovy compile to Java?

Groovy scripts can use any Java classes. They can be compiled to Java bytecode (in . class files) that can be invoked from normal Java classes. The Groovy compiler, groovyc, compiles both Groovy scripts and Java source files, however some Java syntax (such as nested classes) is not supported yet.

Does Groovy need to be compiled?

Unlike Java, a Groovy source code file can be executed as an (uncompiled) script, if it contains code outside any class definition, if it is a class with a main method, or if it is a Runnable or GroovyTestCase. A Groovy script is fully parsed, compiled, and generated before executing (similar to Python and Ruby).

Does Groovy need JDK or JRE?

The answer is yes. In fact, all groovy code compiles down to Java classes that run on the JRE. All you need is JRE 1.4 or higher and the groovy-all-*.


1 Answers

It isn't clear from the description why you are doing the compiling yourself. If you can just let Groovy do it for you then the whole thing can just be simplified to something like this:

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

GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
Class theParsedClass = groovyClassLoader.parseClass(script);
like image 163
Jeff Scott Brown Avatar answered Oct 13 '22 00:10

Jeff Scott Brown