Relates :
|
|
Relates :
|
|
Relates :
|
FULL PRODUCT VERSION : java version "1.8.0_11" Java(TM) SE Runtime Environment (build 1.8.0_11-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.11-b03, mixed mode) ADDITIONAL OS VERSION INFORMATION : Microsoft Windows [Version 6.1.7601] A DESCRIPTION OF THE PROBLEM : Initially i added this here: http://stackoverflow.com/questions/24784792/java8-javascript-nashorn-exception-no-current-global-instance-for-nashorn I want to retrieve object generated in JS store them in Java and later call methods on them. This worked with Java 7, now with Java 8 i get an exception: Exception in thread "main" java.lang.IllegalArgumentException: no current Global instance for nashorn at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:492) at jdk.nashorn.api.scripting.NashornScriptEngine.invokeMethod(NashornScriptEngine.java:238) I have modified the official example from here http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/prog_guide/api.html a bit. Now i created a minimal example to produce this exception. It seems like, if a JS object is passed to Java via return value, it is different to the case JS calls a Java object's method and passes the object. public class InvokeScriptMethod { static Object o1; public static class Context { public void add( Object o ){ InvokeScriptMethod.o1 = o; } } public static void main(String[] args) throws Exception { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("nashorn"); engine.put("ctx", new Context()); engine.eval("function bla(){\n" + "var obj = new Object();\n" + "obj.var1 = 3;\n" + "obj.hello = function(name) { print('Hello, ' + this.var1 + ' ' + name); this.var1++; };\n" + "ctx.add(obj);\n" + "return obj;\n" + "}"); Invocable inv = (Invocable) engine; Object obj = inv.invokeFunction("bla"); System.out.printf("retrieved as return value : %s %s\n", obj.getClass(), obj); System.out.printf("retrieved via call to java object: %s %s\n", o1.getClass(), o1); inv.invokeMethod(obj, "hello", "Script Method!"); inv.invokeMethod(o1, "hello", "Script Method!"); // <-- exception } } program output: retrieved as return value : class jdk.nashorn.api.scripting.ScriptObjectMirror [object Object] retrieved via call to java object: class jdk.nashorn.internal.scripts.JO jdk.nashorn.internal.scripts.JO@105fece7 Hello, 3 Script Method! Exception in thread "main" java.lang.IllegalArgumentException: no current Global instance for nashorn obj is a ScriptObjectMirror as it is expected, o1 is an internal object. http://cr.openjdk.java.net/~sundar/8023631/webrev.00/src/jdk/nashorn/api/scripting/NashornScriptEngine.java.html line 481 shows how this exception is thrown. So I think, there is something wrong by wrapping the "naked" JS object into a ScriptObjectMirror when passing as argument to Java. REGRESSION. Last worked in version 7u10 ADDITIONAL REGRESSION INFORMATION: java version "1.7.0_06" Java(TM) SE Runtime Environment (build 1.7.0_06-b24) Java HotSpot(TM) 64-Bit Server VM (build 23.2-b09, mixed mode) STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : run example code EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - no exception ACTUAL - exception thrown ERROR MESSAGES/STACK TRACES THAT OCCUR : no current Global instance for nashorn REPRODUCIBILITY : This bug can be reproduced always. ---------- BEGIN SOURCE ---------- public class InvokeScriptMethod { static Object o1; public static class Context { public void add( Object o ){ InvokeScriptMethod.o1 = o; } } public static void main(String[] args) throws Exception { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("nashorn"); engine.put("ctx", new Context()); engine.eval("function bla(){\n" + "var obj = new Object();\n" + "obj.var1 = 3;\n" + "obj.hello = function(name) { print('Hello, ' + this.var1 + ' ' + name); this.var1++; };\n" + "ctx.add(obj);\n" + "return obj;\n" + "}"); Invocable inv = (Invocable) engine; Object obj = inv.invokeFunction("bla"); System.out.printf("retrieved as return value : %s %s\n", obj.getClass(), obj); System.out.printf("retrieved via call to java object: %s %s\n", o1.getClass(), o1); inv.invokeMethod(obj, "hello", "Script Method!"); inv.invokeMethod(o1, "hello", "Script Method!"); // <-- exception } } ---------- END SOURCE ----------
|