ToB企服应用市场:ToB评测及商务社交产业平台

标题: 字符串值提取工具-04-java 调用 java? Janino 编译工具 [打印本页]

作者: 渣渣兔    时间: 2024-8-16 00:41
标题: 字符串值提取工具-04-java 调用 java? Janino 编译工具
值提取系列

值提取系列

字符串值提取工具-01-概览
字符串值提取工具-02-java 调用 js
字符串值提取工具-03-java 调用 groovy
字符串值提取工具-04-java 调用 java? Janino 编译工具
字符串值提取工具-05-java 调用 shell
字符串值提取工具-06-java 调用 python
字符串值提取工具-07-java 调用 go
代码地址

value-extraction 值提取核心
场景

我们希望通过 java 执行 java,怎样实现呢?
入门例子

代码
  1. package org.example;
  2. import javax.tools.*;
  3. import java.io.File;
  4. import java.lang.reflect.Method;
  5. import java.net.URI;
  6. import java.net.URL;
  7. import java.net.URLClassLoader;
  8. import java.util.Arrays;
  9. public class DynamicJavaExecutor {
  10.     public static void main(String[] args) {
  11.         // Java 代码字符串
  12.         String javaCode =
  13.                 "public class HelloWorld { " +
  14.                         "    public static void main(String[] args) { " +
  15.                         "        System.out.println("Hello, World!"); " +
  16.                         "    } " +
  17.                         "} ";
  18.         // 编译 Java 代码
  19.         boolean success = compileJavaCode("HelloWorld", javaCode);
  20.         if (success) {
  21.             try {
  22.                 // 使用 URLClassLoader 加载编译后的类
  23.                 File file = new File("./"); // 获取当前目录
  24.                 URL url = file.toURI().toURL(); // 转换为 URL
  25.                 URLClassLoader classLoader = new URLClassLoader(new URL[]{url});
  26.                 Class<?> clazz = classLoader.loadClass("HelloWorld");
  27.                 // 调用类的 main 方法
  28.                 Method mainMethod = clazz.getMethod("main", String[].class);
  29.                 String[] params = null; // 传递给 main 方法的参数
  30.                 mainMethod.invoke(null, (Object) params);
  31.             } catch (Exception e) {
  32.                 e.printStackTrace();
  33.             }
  34.         } else {
  35.             System.out.println("Compilation failed.");
  36.         }
  37.     }
  38.     public static boolean compileJavaCode(String className, String javaCode) {
  39.         // 创建自定义的 JavaFileObject
  40.         JavaFileObject fileObject = new InMemoryJavaFileObject(className, javaCode);
  41.         // 获取系统 Java 编译器
  42.         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
  43.         StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
  44.         // 设置输出目录
  45.         Iterable<String> options = Arrays.asList("-d", "./");
  46.         // 编译 Java 代码
  47.         JavaCompiler.CompilationTask task = compiler.getTask(
  48.                 null,
  49.                 fileManager,
  50.                 null,
  51.                 options,
  52.                 null,
  53.                 Arrays.asList(fileObject)
  54.         );
  55.         // 进行编译
  56.         return task.call();
  57.     }
  58.     // 内部类,用于在内存中表示 Java 源文件
  59.     static class InMemoryJavaFileObject extends SimpleJavaFileObject {
  60.         private final String code;
  61.         protected InMemoryJavaFileObject(String name, String code) {
  62.             super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
  63.             this.code = code;
  64.         }
  65.         @Override
  66.         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
  67.             return code;
  68.         }
  69.     }
  70. }
复制代码
测试效果:
  1. Hello, World!
复制代码
Janino 例子

maven 引入
  1. <dependency>
  2.     <groupId>org.codehaus.janino</groupId>
  3.     <artifactId>janino</artifactId>
  4.     <version>3.1.9</version>
  5. </dependency>
复制代码
代码
  1. package org.example;
  2. import org.codehaus.janino.SimpleCompiler;
  3. public class JaninoExample {
  4.     public static void main(String[] args) throws Exception {
  5.         // Java 代码字符串
  6.         String javaCode =
  7.                 "public class HelloWorld { " +
  8.                         "    public void run() { " +
  9.                         "        System.out.println("Hello, World!"); " +
  10.                         "    } " +
  11.                         "} ";
  12.         // 创建编译器实例
  13.         SimpleCompiler compiler = new SimpleCompiler();
  14.         // 编译 Java 代码
  15.         compiler.cook(javaCode);
  16.         // 获取编译后的类
  17.         Class<?> clazz = compiler.getClassLoader().loadClass("HelloWorld");
  18.         // 创建类的实例
  19.         Object instance = clazz.getDeclaredConstructor().newInstance();
  20.         // 调用 run 方法
  21.         clazz.getMethod("run").invoke(instance);
  22.     }
  23. }
复制代码
直接执行该方法
  1. package com.github.houbb.value.extraction.test;
  2. import org.codehaus.janino.ScriptEvaluator;
  3. public class JavaDemoTest {
  4.     public static void main(String[] args) throws Exception {
  5.         // Java 脚本字符串
  6.         String script =
  7.                 "System.out.println("Hello, World!");";
  8.         // 创建脚本求值器实例
  9.         ScriptEvaluator scriptEvaluator = new ScriptEvaluator();
  10.         // 编译并执行脚本
  11.         scriptEvaluator.cook(script);
  12.         scriptEvaluator.evaluate(null);
  13.     }
  14. }
复制代码
传入参数,直接执行
  1. package com.github.houbb.value.extraction.test;
  2. import org.codehaus.janino.ScriptEvaluator;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. public class JaninoExample {
  6.     public static void main(String[] args) throws Exception {
  7.         // 创建一个包含参数的 Map
  8.         Map<String, Object> bindings = new HashMap<>();
  9.         bindings.put("a", 10);
  10.         bindings.put("b", 20);
  11.         // 定义要执行的脚本
  12.         String script = "System.out.println("Result: " + (a + b));";
  13.         // 调用方法来执行脚本
  14.         executeScriptWithBindings(script, bindings);
  15.     }
  16.     public static void executeScriptWithBindings(String script, Map<String, Object> bindings) throws Exception {
  17.         // 提取 Map 中的键(参数名)和值(参数值)
  18.         String[] parameterNames = bindings.keySet().toArray(new String[0]);
  19.         Class<?>[] parameterTypes = new Class<?>[parameterNames.length];
  20.         // 假设所有参数的类型都是 Object,可以根据需要修改类型推断逻辑
  21.         for (int i = 0; i < parameterNames.length; i++) {
  22.             parameterTypes[i] = bindings.get(parameterNames[i]).getClass();
  23.         }
  24.         // 创建 ScriptEvaluator 实例
  25.         ScriptEvaluator scriptEvaluator = new ScriptEvaluator();
  26.         // 设置脚本的参数名称和类型
  27.         scriptEvaluator.setParameters(parameterNames, parameterTypes);
  28.         // 编译脚本
  29.         scriptEvaluator.cook(script);
  30.         // 提取 Map 中的值作为参数
  31.         Object[] parameterValues = bindings.values().toArray();
  32.         // 执行脚本
  33.         scriptEvaluator.evaluate(parameterValues);
  34.     }
  35. }
复制代码
但是感觉这个很麻烦,而且有问题
另一种执行的方式
  1. package com.github.houbb.value.extraction.test.javas;
  2. import org.codehaus.commons.compiler.CompileException;
  3. import org.codehaus.janino.ScriptEvaluator;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. public class JaninoScriptMapExample {
  8.     public static void main(String[] args) throws CompileException, InvocationTargetException {
  9.         // 示例脚本,使用 Map 参数
  10.         String script =
  11.                 "return map.get("greeting") + ", " + map.get("name") + "!";";
  12.         // 创建 ScriptEvaluator 实例,指定返回类型、参数名和参数类型
  13.         ScriptEvaluator se = new ScriptEvaluator(
  14.                 script,                      // 脚本代码
  15.                 Object.class,                // 返回值类型
  16.                 new String[]{"map"},         // 参数名列表
  17.                 new Class<?>[]{Map.class}    // 参数类型列表
  18.         );
  19.         // 准备传入的 Map 参数
  20.         Map<String, Object> params = new HashMap<>();
  21.         params.put("greeting", "Hello");
  22.         params.put("name", "Janino");
  23.         // 执行脚本,传入 Map 参数
  24.         Object result = se.evaluate(new Object[]{params});
  25.         // 输出结果
  26.         System.out.println(result);
  27.     }
  28. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4