Hi,
In Nashorn, each ENGINE_SCOPE Bindings instance is associated with it's
own Nashorn global instance (an instance of
jdk.nashorn.internal.objects.Global class). i.e., each ENGINE_SCOPE
Bindings instance is associated with a fresh ECMAScript/JS global scope
object - with it's own "Object", "Function", "RegExp" etc.
Nashorn represents script objects crossing JS global boundary as
ScriptObjectMirror instances. ScriptObjectMirror is also the way Java
code can access any script object (without having to deal with internal
jdk.nashorn.internal.runtime.ScriptObject). See also:
https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/ScriptObjectMirror.html
If you access a script object from a JS global scope g1 from another JS
global scope g2, you'll get a ScriptObjectMirror wrap. Nashorn attempts
to provide seamless integration of ScriptObjectMirror instances - you
can treat ScriptObjectMirrors almost like those are script objects. But
this integration is not complete. Please see also:
https://wiki.openjdk.java.net/display/Nashorn/Nashorn+jsr223+engine+notes
Not every JS API can work with ScriptObjectMirrors (like these APIs work
with script objects that belong to the "current" JS global scope).
Object.create is one such API. You can adjust your code slightly. For
example:
import javax.script.*;
import jdk.nashorn.api.scripting.*;
public class Main {
public static void main(String[] args) throws Exception {
ScriptEngine e = new
ScriptEngineManager().getEngineByName("nashorn");
e.put("foo", e.eval("function() { return {} }", new
SimpleBindings()));
// get "foo"
ScritptObjectMirror foo = (ScriptObjectMirror)e.get("foo");
// eval Object.create in the global where "foo" belongs - with
"foo" set as "this"
System.out.println(foo.eval("Object.create(this)"));
}
}
Hope this helps,
-Sundar
On 01/03/17, 2:35 AM, Frantzius, Jörg wrote:
Hi,
in my code I’m running into an issue for which
https://github.com/coveo/nashorn-commonjs-modules/issues/3 luckily provides a
snippet for reproducing:
@Test
public void testObjectCreateOnFunction() throws ScriptException {
ScriptEngine engine = new
ScriptEngineManager().getEngineByName("nashorn");
engine.put("foo", engine.eval("function() { return {}; }", new
SimpleBindings()));
engine.eval("Object.create(foo());");
}
This fails with:
Caused by:<eval>:1 TypeError: [object Object] is not an Object
at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:213)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:185)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:172)
at jdk.nashorn.internal.objects.Global.checkObject(Global.java:2073)
at jdk.nashorn.internal.objects.NativeObject.create(NativeObject.java:261)
at jdk.nashorn.internal.scripts.Script$21$\^eval\_.:program(<eval>:1)
at
jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:623)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at
jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
... 31 more
In my own code, the pattern is slightly different, but it fails similarly
(SimpleScriptContext internally uses SimpleBindings as well):
@Test
public void testObjectCreateInFunction() throws ScriptException {
ScriptEngine engine = new
ScriptEngineManager().getEngineByName("nashorn");
SimpleScriptContext context = new SimpleScriptContext();
context.setAttribute("f", engine.eval("(function ()
{Object.create(this)})"), ScriptContext.ENGINE_SCOPE);
engine.eval("f.call({})", context);
}
The issue seems to be that the function object internally isn’t turned from
ScriptObjectMirror into ScriptObject, so Global.checkObject() fails.
I’d be thankful for any hints on whether this may be a bug or intended
behaviour.
Regards,
Jörg
---
Dipl. Inf. Jörg von Frantzius, Technical Director
E-Mail joerg.frantz...@aperto.com
Phone +49 30 283921-318
Fax +49 30 283921-29
Aperto GmbH – An IBM Company
Chausseestraße 5, D-10115 Berlin
http://www.aperto.com<http://www.aperto.de/>
http://www.facebook.com/aperto
https://www.xing.com/companies/apertoag
HRB 77049 B, AG Berlin Charlottenburg
Geschäftsführer: Dirk Buddensiek, Kai Großmann, Stephan Haagen, Daniel Simon