值提取系列
值提取系列
字符串值提取工具-01-概览
字符串值提取工具-02-java 调用 js
字符串值提取工具-03-java 调用 groovy
字符串值提取工具-04-java 调用 java? Janino 编译工具
字符串值提取工具-05-java 调用 shell
字符串值提取工具-06-java 调用 python
字符串值提取工具-07-java 调用 go
代码地址
value-extraction 值提取核心
场景
我们希望通过 java 执行 java,怎样实现呢?
入门例子
代码
- package org.example;
- import javax.tools.*;
- import java.io.File;
- import java.lang.reflect.Method;
- import java.net.URI;
- import java.net.URL;
- import java.net.URLClassLoader;
- import java.util.Arrays;
- public class DynamicJavaExecutor {
- public static void main(String[] args) {
- // Java 代码字符串
- String javaCode =
- "public class HelloWorld { " +
- " public static void main(String[] args) { " +
- " System.out.println("Hello, World!"); " +
- " } " +
- "} ";
- // 编译 Java 代码
- boolean success = compileJavaCode("HelloWorld", javaCode);
- if (success) {
- try {
- // 使用 URLClassLoader 加载编译后的类
- File file = new File("./"); // 获取当前目录
- URL url = file.toURI().toURL(); // 转换为 URL
- URLClassLoader classLoader = new URLClassLoader(new URL[]{url});
- Class<?> clazz = classLoader.loadClass("HelloWorld");
- // 调用类的 main 方法
- Method mainMethod = clazz.getMethod("main", String[].class);
- String[] params = null; // 传递给 main 方法的参数
- mainMethod.invoke(null, (Object) params);
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- System.out.println("Compilation failed.");
- }
- }
- public static boolean compileJavaCode(String className, String javaCode) {
- // 创建自定义的 JavaFileObject
- JavaFileObject fileObject = new InMemoryJavaFileObject(className, javaCode);
- // 获取系统 Java 编译器
- JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
- // 设置输出目录
- Iterable<String> options = Arrays.asList("-d", "./");
- // 编译 Java 代码
- JavaCompiler.CompilationTask task = compiler.getTask(
- null,
- fileManager,
- null,
- options,
- null,
- Arrays.asList(fileObject)
- );
- // 进行编译
- return task.call();
- }
- // 内部类,用于在内存中表示 Java 源文件
- static class InMemoryJavaFileObject extends SimpleJavaFileObject {
- private final String code;
- protected InMemoryJavaFileObject(String name, String code) {
- super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
- this.code = code;
- }
- @Override
- public CharSequence getCharContent(boolean ignoreEncodingErrors) {
- return code;
- }
- }
- }
复制代码 测试效果:Janino 例子
maven 引入
- <dependency>
- <groupId>org.codehaus.janino</groupId>
- <artifactId>janino</artifactId>
- <version>3.1.9</version>
- </dependency>
复制代码 代码
- package org.example;
- import org.codehaus.janino.SimpleCompiler;
- public class JaninoExample {
- public static void main(String[] args) throws Exception {
- // Java 代码字符串
- String javaCode =
- "public class HelloWorld { " +
- " public void run() { " +
- " System.out.println("Hello, World!"); " +
- " } " +
- "} ";
- // 创建编译器实例
- SimpleCompiler compiler = new SimpleCompiler();
- // 编译 Java 代码
- compiler.cook(javaCode);
- // 获取编译后的类
- Class<?> clazz = compiler.getClassLoader().loadClass("HelloWorld");
- // 创建类的实例
- Object instance = clazz.getDeclaredConstructor().newInstance();
- // 调用 run 方法
- clazz.getMethod("run").invoke(instance);
- }
- }
复制代码 直接执行该方法
- package com.github.houbb.value.extraction.test;
- import org.codehaus.janino.ScriptEvaluator;
- public class JavaDemoTest {
- public static void main(String[] args) throws Exception {
- // Java 脚本字符串
- String script =
- "System.out.println("Hello, World!");";
- // 创建脚本求值器实例
- ScriptEvaluator scriptEvaluator = new ScriptEvaluator();
- // 编译并执行脚本
- scriptEvaluator.cook(script);
- scriptEvaluator.evaluate(null);
- }
- }
复制代码 传入参数,直接执行
- package com.github.houbb.value.extraction.test;
- import org.codehaus.janino.ScriptEvaluator;
- import java.util.HashMap;
- import java.util.Map;
- public class JaninoExample {
- public static void main(String[] args) throws Exception {
- // 创建一个包含参数的 Map
- Map<String, Object> bindings = new HashMap<>();
- bindings.put("a", 10);
- bindings.put("b", 20);
- // 定义要执行的脚本
- String script = "System.out.println("Result: " + (a + b));";
- // 调用方法来执行脚本
- executeScriptWithBindings(script, bindings);
- }
- public static void executeScriptWithBindings(String script, Map<String, Object> bindings) throws Exception {
- // 提取 Map 中的键(参数名)和值(参数值)
- String[] parameterNames = bindings.keySet().toArray(new String[0]);
- Class<?>[] parameterTypes = new Class<?>[parameterNames.length];
- // 假设所有参数的类型都是 Object,可以根据需要修改类型推断逻辑
- for (int i = 0; i < parameterNames.length; i++) {
- parameterTypes[i] = bindings.get(parameterNames[i]).getClass();
- }
- // 创建 ScriptEvaluator 实例
- ScriptEvaluator scriptEvaluator = new ScriptEvaluator();
- // 设置脚本的参数名称和类型
- scriptEvaluator.setParameters(parameterNames, parameterTypes);
- // 编译脚本
- scriptEvaluator.cook(script);
- // 提取 Map 中的值作为参数
- Object[] parameterValues = bindings.values().toArray();
- // 执行脚本
- scriptEvaluator.evaluate(parameterValues);
- }
- }
复制代码 但是感觉这个很麻烦,而且有问题
另一种执行的方式
- package com.github.houbb.value.extraction.test.javas;
- import org.codehaus.commons.compiler.CompileException;
- import org.codehaus.janino.ScriptEvaluator;
- import java.lang.reflect.InvocationTargetException;
- import java.util.HashMap;
- import java.util.Map;
- public class JaninoScriptMapExample {
- public static void main(String[] args) throws CompileException, InvocationTargetException {
- // 示例脚本,使用 Map 参数
- String script =
- "return map.get("greeting") + ", " + map.get("name") + "!";";
- // 创建 ScriptEvaluator 实例,指定返回类型、参数名和参数类型
- ScriptEvaluator se = new ScriptEvaluator(
- script, // 脚本代码
- Object.class, // 返回值类型
- new String[]{"map"}, // 参数名列表
- new Class<?>[]{Map.class} // 参数类型列表
- );
- // 准备传入的 Map 参数
- Map<String, Object> params = new HashMap<>();
- params.put("greeting", "Hello");
- params.put("name", "Janino");
- // 执行脚本,传入 Map 参数
- Object result = se.evaluate(new Object[]{params});
- // 输出结果
- System.out.println(result);
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |