Location>code7788 >text

Java Dynamic Compilation Tools Janino and Liquor Differences

Popularity:1 ℃/2024-09-24 09:40:01

If you only need Java 7 and below, we recommend Janino, but if you want a fuller range of Java 8, Java 11, Java 17, Java 21, etc., you can go with Liquor.

1. Where they are the same

  • Similar capability interfaces provided
connector Janino Liquor
Dynamic compiler SimpleCompiler DynamicCompiler
expression evaluator ExpressionEvaluator LiquorEvaluator (Exprs)
Script Evaluator ScriptEvaluator LiquorEvaluator (Scripts)
  • All are dynamic applications of the Java language (syntax). The generated bytecode all have full access to the JRE, may have to pay attention to security controls.

2. Details of the difference

  • Janino's implementation is based on its own compilation capabilities.
    • Support for Java 7 and below syntax.
    • Single compilation performance, better.
    • Command line compilation is supported.
    • Provide richer functionality. For example, code analyzer, etc.
  • Liquor is implemented based on the compilation capabilities that come with the JDK.
    • Support for Java8, Java11, Java17, Java21 and other syntaxes (determined by runtime version).
    • Single compilation performance, poorer.
    • Command line compilation is not supported. The javac command is available.

3. Specific Differences - Dynamic Compiler

The performance of a dynamic compiler can basically be measured in "times". The more times, the more time it takes. Try to compile as much knowable code as possible together (the fewer times, the better).

  • Janino
public class JaninoTest {
    public static void main(String[] args) throws Exception {
        //these kinds,not reusable(It can be done in other ways.,Implementing Multiple Classes Compiled Together)
        SimpleCompiler compiler = new SimpleCompiler();
        
        String className = "HelloWorld";
        String classCode = "public class HelloWorld { " +
                " public static void helloWorld() { " +
                " (\"Hello, world!\"); " +
                "   } " +
                "}";
        
        //Can only be compiled individually
        (classCode);
        
        //then (after sth, and not until then) cook ,then it will be an exception

        Class<?> clazz = ().loadClass(className);
        ("helloWorld").invoke(null);
    }
}
  • Liquor
public class LiquorTest {
    public static void main(String[] args) throws Exception{
        //reusable(can,Constant incremental compilation)
        DynamicCompiler compiler = new DynamicCompiler();
        
        String className = "HelloWorld";
        String classCode = "public class HelloWorld { " +
                " public static void helloWorld() { " +
                " (\"Hello, world!\"); " +
                "   } " +
                "}";
        
        //Multiple source codes can be added
        (className, classCode);
        ();
        
        //post-construction,It is still possible to add source code for different classes and then build the

        Class<?> clazz = ().loadClass(className);
        ("helloWorld").invoke(null);
    }
}

4. Specific Differences - Expression Evaluator

comparisons Janino Liquor
(computing) cache None (you can pack it yourself) There is a second level cache (class loader cache, compilation result cache)
experience for oneself Each time you want to rebuild the (euphemism) go to the toilet
performances Better on a single occasion Very good (close to raw Java code performance) when caching naming
  • Janino
public class JaninoTest {
    public static void main(String[] args) throws Exception {
        //Each time you want to newly instantiate the
        ExpressionEvaluator ee = new ExpressionEvaluator();
        ("3 + 4");
        (());
    }
}
  • Liquor
public class LiquorTest {
    public static void main(String[] args) throws Exception {
        //singleton example,reusable,thread safety
        (("3 + 4"));
    }
}

5. Specific Differences - Script Evaluator

comparisons Janino Liquor
(computing) cache None (you can pack it yourself) There is a second level cache (class loader cache, compilation result cache)
experience for oneself Each time you want to rebuild the (euphemism) go to the toilet
performances Better on a single occasion Very good (close to raw Java code performance) when caching naming
  • Janino
public class JaninoTest {
    public static void main(String[] args) throws Exception {
        //Each time you want to newly instantiate the
        ScriptEvaluator se = new ScriptEvaluator();
        ("(\"hello word\");");
        ();
    }
}
  • Liquor
public class LiquorTest {
    public static void main(String[] args) throws Exception {
        //singleton example,reusable,thread safety
        ("(\"hello word\");");
    }
}