1. Javascript Engine
public class MainTest {
public static void main(String[] args)throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval("7/7+9-9*5/5");
System.out.println(result);
}
}
2. Java Compiler
a) Compile string into Java class
b) Load the class using a custom ClassLoader.
c) Excute it using reflect.
Here's a sample:
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
public class MainTest{
public static void eval(String str) throws Exception{
StringBuffer sb = new StringBuffer();
sb.append("public class TempClass{\n");
sb.append(" public void run(){\n");
sb.append(" " + str + "\n");
sb.append(" }\n");
sb.append("}\n");
System.out.println(sb.toString());
Class clazz = new EvalClassLoader().findClass(sb.toString());
Method method = clazz.getMethod("run");
method.invoke(clazz.newInstance());
}
public static void main(String[] args) throws Exception {
eval("System.out.println(7/7+9-9*5/5);");
}
}
/**
* A custom class Loader.
*/
class EvalClassLoader extends ClassLoader{
private String tempCLassName = "TempClass";
@Override
protected Class<?> findClass(String codeStr) throws ClassNotFoundException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaFileObject file = new ClassFromString(tempCLassName, codeStr.toString());
// Start a compile task
Iterable<JavaFileObject> compilationUnits = Arrays.asList(file);
JavaCompiler.CompilationTask task = compiler
.getTask(null, null, null, null, null, compilationUnits);
if(task.call()){
return loadClass(tempCLassName);
}
return null;
}
}
/**
* A Java class constructed from String.
*/
class ClassFromString extends SimpleJavaFileObject{
private String code;
public ClassFromString(String className,String code){
super(URI.create("string:///" + className.replace('.', '/') +
Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors)
throws IOException {
return code;
}
}