# liquor **Repository Path**: javakf/liquor ## Basic Information - **Project Name**: liquor - **Description**: Java 动态编译、表达式、脚本工具(兼容 jar in jar) - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 67 - **Created**: 2024-09-21 - **Last Updated**: 2024-09-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

Liquor

Java 动态编译、表达式、脚本工具(兼容 jar in jar)

Maven Apache 2 jdk-8 jdk-11 jdk-17 jdk-21 jdk-22
gitee star github star



本工具的编译器代码主要源自 arthas。相关的知识点比较冷门,甚是珍贵。为了复用方便,特整理成一个小工具包进行长期维护。后来又增加了表达式、脚本支持。 | 工件 | 大小 | 功能 | 功能描述 | |----------------|------|---------------------------------------------------------|-----------------------| | liquor | 24KB | DynamicCompiler | 编译一个或多个类 | | liquor-eval | 16KB | ExpressionEvaluator, Exprs
ScriptEvaluator, Scripts | 评估表达式(就是,运行)
评估脚本 | 引用依赖: ```xml org.noear liquor-eval 1.3.0 ``` 性能表现(第三方性能测试,榜首): * [https://gitee.com/xiandafu/beetl/tree/master/express-benchmark](https://gitee.com/xiandafu/beetl/tree/master/express-benchmark) ## 编译器演示 可以有包名;可以导入类;可相互依赖;可多次不重复编译;跟平常写 java 类一样。 ```java public class DemoApp { public static void main(String[] args) throws Exception{ //可以复用(不要,不断的新建) DynamicCompiler compiler = new DynamicCompiler(); String className = "HelloWorld"; String classCode = "import java.util.HashMap;\n\n"+ "public class HelloWorld { " + " public static void helloWorld() { " + " System.out.println(\"Hello, world!\"); " + " } " + "}"; //添加源码(可多个)并 构建 compiler.addSource(className, classCode).build(); Class clazz = compiler.getClassLoader().loadClass(className); clazz.getMethod("helloWorld").invoke(null); } } ``` ## 评估器演示 内部会把评估代码编译为一个静态方法 ### 1) 表达式评估器(只能写一行代码) * 必须有结果返回 * 表达式中没有 ";" 时,评估器会自动添加 "return" 和 ";"。否则要自己确保语句完整 * 使用 CodeSpec::imports 导入表达式需要的类 ```java public class DemoApp { public static void main(String[] args) throws Exception { //基础 System.out.println(Exprs.eval("1+1")); //进阶 CodeSpec code1 = new CodeSpec("aa + 22").parameters(new ParamSpec("aa", Integer.class)); System.out.println(Exprs.eval(code1, 1)); //=> 23 Map context2 = new HashMap<>(); context2.put("bb", 3); System.out.println(Exprs.eval("bb + 22", context2)); //=>25 System.out.println(Exprs.eval(new CodeSpec("Math.min(1,2)").imports(Math.class))); //=>1 } } ``` ### 2) 脚本评估器 * 可以导入类;不能有包名 * 使用内部类时不要加 "public" 修饰 * 使用 CodeSpec::imports 导入表达式需要的类;或者在代码里添加 "import" 语句 ```java public class DemoApp { public static void main(String[] args) throws Exception { //基础 Scripts.eval("System.out.println(\"hello word\");"); //进阶(如果有内部类,不要加 public) CodeSpec code1 = new CodeSpec("import java.util.HashMap;\n\n"+ " class Demo {\n" + " public String hello(String word) {\n" + " return word;\n" + " }\n" + " }\n" + "\n" + " Demo demo = new Demo();\n" + " return demo.hello(name);") //name 为外部参数 .parameters(new ParamSpec("name", String.class)) .returnType(String.class); System.out.println(Scripts.eval(code1, "noear")); //=>noear } } ```