先贴个笔记,后续用得着再深究。
package test; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import javax.tools.JavaCompiler; import javax.tools.ToolProvider; public class SimpleRun { public static void showCompile() { // Prepare source somehow. String source = "package test; public class Test { static { System.out.println(\"hello\"); } public Test() { System.out.println(\"world\");} public void Hello(){System.out.println(\"fuck\");} }"; // Save source in .java file. File root = new File("~/temp"); // On Windows running on C:\, this is // C:\java. File sourceFile = new File(root, "test/Test.java"); sourceFile.getParentFile().mkdirs(); try { Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8)); // Compile source file. JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); int success = compiler.run(null, null, null, sourceFile.getPath()); if (success == 0) { // Load and instantiate compiled class. URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() }); Class<?> cls; try { // Should print "hello". cls = Class.forName("test.Test", true, classLoader); // Should print "world". Object instance = cls.newInstance(); // Should print "test.Test@hashcode". System.out.println(instance); Method m = cls.getMethod("Hello", new Class<?>[] {}); System.out.println(m); m.invoke(instance, new Object[]{}); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } else { System.out.println("compile failed"); } } catch (IOException e) { e.printStackTrace(); } } private static double calculate(String expr) { String className = "Calculator"; String methodName = "calculate"; String source = "package test; public class " + className + " { public static double " + methodName + "() { return " + expr + "; } }"; // set work directory File root = new File("~/temp"); // set work package File sourceFile = new File(root, "test/Calculator.java"); sourceFile.getParentFile().mkdirs(); try { Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8)); // Compile source file. JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); int success = compiler.run(null, null, null, sourceFile.getPath()); if (success == 0) { // Load and instantiate compiled class. URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() }); Class<?> cls; try { cls = Class.forName("test.Calculator", true, classLoader); Object instance = cls.newInstance(); Method method = cls.getMethod(methodName, new Class<?>[] {}); Object value = method.invoke(instance, new Object[] {}); return (Double) value; } catch (ClassNotFoundException | IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } } else { System.out.println("compile failed"); } } catch (IOException e) { e.printStackTrace(); } return 0.0; } public static void main(String[] args) { SimpleRun.showCompile(); if (args.length >= 1) { System.out.println(args[0] + "=" + SimpleRun.calculate(args[0])); } } }
参考:
http://www.infoq.com/cn/articles/cf-java-byte-code