Implementation steps:
1. Customize a Java class that defines a method to contain the code that needs to be run.
2. Dynamically compile the Java source code just generated, do not generate the source code on the disk, but directly compile the in-memory Java source code.
3. Dynamically load the Java binary code that just created the compilation, the compiled Java binary code is not on disk, but in memory, and defines its own class loader, responsible for loading the in-memory class file.
4. Run the class loaded in the previous step by reflection.
Import Java.util.Arrays; Import Javax.tools.SimpleJavaFileObject; Import Javax.tools.JavaFileObject; Import Javax.tools.JavaCompiler; Import Javax.tools.ToolProvider; Import Javax.tools.DiagnosticCollector; Import Java.net.URI; /** * Description: * <br/> website: <a href= "http://www.crazyit.org" mce_href= "http://www.crazyit.org" > Crazy Java Federation </a> * <br/>copyright (C), 2001-2010, Leeyohn * <br/>this program was protected by copyright laws. * <br/>program Name: * <br/>date: * @author Leeyohn [email protected] * @version 1.0 */
Public class Myclassloader extends ClassLoader { @Override public class<?> findclass (String str ) throws ClassNotFoundException { Javacompiler compiler = Toolprovider.getsystemjavacompiler (); // Object used to diagnose source code compilation errors Diagnosticcollector diagnostics = new Diagnosticcollector (); // The in-memory source code is saved in a class that inherits from Javafileobject Javafileobject file = new Javasourcefromstring ("Temp", str.tostring ()); Iterable compilationunits = arrays.aslist (file); //Build a compilation task Javacompiler.compilationtask task = Compiler.gettask (null, NULL, NULL, NULL, NULL, compilationunits) ; //Compile source program Boolean result = Task.call (); if (result) { return class.forname ("Temp"); } return null; } } Class Javasourcefromstring extends Simplejavafileobject { private String name; Private String Code; Public javasourcefromstring (string name, string code) { Super (Uri.create ("string:///" + name.replace ('. ', '/') + Kind.SOURCE.extension), kind.source); This.code = code; } Public Charsequence getcharcontent (Boolean ignoreencodingerrors) { return code; } } |
Import Java.lang.reflect.Method; /** * Description: * <br/> website: <a href= "http://www.crazyit.org" mce_href= "http://www.crazyit.org" > Crazy Java Federation </a> * <br/>copyright (C), 2001-2010, Leeyohn * <br/>this program was protected by copyright laws. * <br/>program Name: * <br/>date: * @author Leeyohn [email protected] * @version 1.0 */ public class Eval { public static Object eval (String str) throws Exception { StringBuffer sb = new StringBuffer (); Sb.append ("public class Temp"); Sb.append ("{"); Sb.append ("Public Object GetObject ()"); Sb.append ("{"); Sb.append ("+ str +" return new Object (); "); Sb.append ("}"); Sb.append ("}"); Call the custom ClassLoader to load the compiled in-memory class file Class clazz = new Myclassloader (). Findclass (Sb.tostring ()); method = Clazz.getmethod ("GetObject"); Calling methods by reflection Return Method.invoke (Clazz.newinstance ()); } public static void Main (string[] args) throws Exception { Object rval = eval ("System.out.println (/" Hello world/");"); System.out.println (Rval); } } |
The eval () function in Java version of implementation JavaScript