Janino compiler for on-the-fly dynamic code compilation

Written on January 18, 2022 by Vatsal Mevada |

I got to know about Janino when I got the opportunity to work on Apache Spark internals at one of my previous organizations.

With the release of version 2.0, Apache Spark started using Whole-stage Code Generation instead of Volcano Iterator Model. Covering the details of Whole-stage Code Generation and Volcano Iterator Model will be out of scope for this post, however, this blog post explains both these concepts in detail.

The Whole-stage Code Generator generates Java code for a specific stage of a Spark job and Spark uses Janino to compile this dynamically generated code on-the-fly.

The latest version of the Janino compiler maven package can be found here and can be included as part of your project.

The following code demonstrates the compilation of a Hello World Java program using Janino:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.janino.ClassBodyEvaluator;

public class HelloWorldJanino {

    public static void main(String[] args) throws CompileException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        String codeString = "public static void main(String[] args) {" +
                            "   System.out.println(\"Hello World!\" );" +
                            "}";

        // Compile the class body, and get the loaded class
        Class<?> cl = new ClassBodyEvaluator(codeString).getClazz();

        // Invoke the "public static main(String[])" method
        Method mainMeth = cl.getMethod("main", String[].class);

        mainMeth.invoke(null, new Object[]{new String[]{}});
    }
}

Link to source code: https://github.com/geekprompt/code-examples/tree/master/janino

References:

Janino compiler official site
Apache Spark as a Compiler: Joining a Billion Rows per Second on a Laptop