package com.deepnighttwo.scriptinjava; import javax.script.Bindings; import javax.script.Invocable; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import com.deepnighttwo.commonjavacode.JavaClassForScript; public class ScriptInJavaMainApp { /** * @param args * @throws ScriptException * @throws NoSuchMethodException */ public static void main(String[] args) throws ScriptException, NoSuchMethodException { ScriptEngineManager seManager = new ScriptEngineManager(); ScriptEngine jsEngine = seManager.getEngineByName("javascript"); if (jsEngine == null) { System.out.println("No engine found for javascript"); System.exit(1); } jsEngine.eval("println('Coooool! Let\\'s Rock \\'n Roll with JS in java now!');"); /** Context and bindings */ System.out.println("=======About Bindings======="); aboutBindings(jsEngine); System.out.println("============================"); System.out.println(""); defineFunctionAddInJs(jsEngine); jsEngine.put("javaClassForJS", new JavaClassForScript()); /** call java method from JS */ System.out.println("=======Interactions between java and js======="); invokeJavaUsingJs(jsEngine); System.out.println("=============================================="); System.out.println(""); /** invoke js function using js, using java and performance test */ System.out.println("=======Performance Test======="); int loop = 1000000; long start = System.currentTimeMillis(); invokeJsLoopFunctionUsingJs(jsEngine, loop); System.out.println("JS loop (from js) uses " + (System.currentTimeMillis() - start) / 1000 + " sec(s)."); start = System.currentTimeMillis(); for (int i = 0; i < loop; i++) { @SuppressWarnings("unused") int num = 9 + 8; } System.out.println("Java uses " + (System.currentTimeMillis() - start) + " mill sec(s)."); start = System.currentTimeMillis(); for (int i = 0; i < loop; i++) { invokeJsFunctionUsingJs(jsEngine, i); } System.out.println("JS (from js) uses " + (System.currentTimeMillis() - start) / 1000 + " sec(s)."); start = System.currentTimeMillis(); for (int i = 0; i < loop; i++) { invokeJsFunctionUsingJava(jsEngine, i); } System.out.println("JS (from java) uses " + (System.currentTimeMillis() - start) / 1000 + " sec(s)."); System.out.println("============================="); start = System.currentTimeMillis(); invokeJavaFromJS(jsEngine, 7, loop); System.out.println("Call Java using JS uses " + (System.currentTimeMillis() - start) / 1000 + " sec(s)."); System.out.println("============================="); } private static void defineFunctionAddInJs(ScriptEngine jsEngine) throws ScriptException { jsEngine.eval("function addTwoNumbers(value){var num = 9+8+value}"); } private static void invokeJsFunctionUsingJs(ScriptEngine jsEngine, int i) throws ScriptException { jsEngine.eval("addTwoNumbers(" + i + ")"); } private static void invokeJsLoopFunctionUsingJs(ScriptEngine jsEngine, int i) throws ScriptException { jsEngine.eval("for(var v=0;v<" + i + ";v++){addTwoNumbers(" + i + ")}"); } private static void invokeJsFunctionUsingJava(ScriptEngine jsEngine, int i) throws ScriptException, NoSuchMethodException { Invocable invocable = (Invocable) jsEngine; invocable.invokeFunction("addTwoNumbers", i); } private static void invokeJavaFromJS(ScriptEngine jsEngine, int i, int loop) throws ScriptException { jsEngine.eval("for(var v=0;v<" + loop + ";v++){javaClassForJS.addTwoNumbers(" + i + ")}"); } private static void invokeJavaUsingJs(ScriptEngine jsEngine) throws ScriptException { // add an object to ENGINE_SCOPE jsEngine.eval("println('Invoking java code from JS...');" + "var num = javaClassForJS.getRandomNumber(99);" + "println('Number returned from java is '+num);" + "var str = javaClassForJS.getRandomString('GoGoGo');" + "println('String returned from java is '+str);" + "var stNum = javaClassForJS.getRandomNumberStatic(987);" + "println('Number returned from java static method is '+stNum);"); // all variables created in javascript are stored in ENGINE_SCOPE // bindings System.out.println("Get variables from js in java:"); System.out.println(jsEngine.get("num")); Object jsObject = jsEngine.get("str"); System.out.println(jsObject); System.out.println(jsEngine.get("stNum")); } private static void aboutBindings(ScriptEngine jsEngine) throws ScriptException { Bindings bindings = jsEngine.createBindings(); bindings.put("value", "Value from bindings conext"); jsEngine.eval("println(value)", bindings); // the following code will trigger an exception try { jsEngine.eval("println(value)"); } catch (ScriptException ex) { System.out.println("Exception :" + ex.getMessage()); } // here is the script engine runtime context ScriptContext scriptConext = jsEngine.getContext(); System.out.println(scriptConext); // just for this script engine; Bindings engineBindings = jsEngine .getBindings(ScriptContext.ENGINE_SCOPE); System.out.println(engineBindings.size()); // shared with all script engines created by the same // ScriptEngineManager System.out.println(jsEngine.getBindings(ScriptContext.GLOBAL_SCOPE) .size()); // set ENGINE_SCOPE bindings and now the invocation has no exception. jsEngine.setBindings(bindings, ScriptContext.ENGINE_SCOPE); jsEngine.eval("println(value)"); } }